如何让 Moose 返回子类实例而不是它自己的类,以实现多态性
我想创建一个泛型类,其构建器不会返回该泛型类的实例,而是返回专用子类的实例。
由于 Moose 会自动构建对象,所以我不明白这是否可能,以及如何使用 Moose 语法创建 Moose 类并具有这种行为。
例如: 用户询问: $file = Repository->new(uri=>'sftp://blabla')
.... 并返回一个 `Repository::_Sftp`` 实例,
用户将使用 $file
就好像它是一个 Repository 实例,而不需要知道真正的子类(多态性)
注意:
根据要求,也许我应该更清楚我想要实现的目标:
我的类的目的是能够添加新的存储库方案(例如通过 sftp),只需创建一个“隐藏”Repository::_Stfp 类,并在存储库构造函数中添加一个案例,根据 url 工厂正确的专用对象。存储库就像一个虚拟基类,提供专门对象将实现的接口。
所有这些都是为了添加新的存储库方案,而不需要修改程序的其余部分:它会在不知不觉中处理专用实例,就好像它是存储库实例一样。
I want to create a generic class, whose builder would not return an instance of this generic class, but an instance of a dedicated child class.
As Moose does automatic object building, I do not get to understand if this something possible, and how to create a Moose class with Moose syntax and having this behaviour.
e.g.:
The user asks: $file = Repository->new(uri=>'sftp://blabla')
.... and is returned an `Repository::_Sftp`` instance
User would use $file
as if it is a Repository instance, without the need to know the real subclass (polymorphism)
Note:
As requested, maybe i should have been more clear about what i was trying to achieve:
The purpose of my class is to be able to add new Repository schemes (eg over sftp), by simply creating an "hidden" Repository::_Stfp class, and adding a case in the Repository constructor to factory the correct specialized object depending of url. Repository would be like a virtual base class, providing an interface that specialized objects would implement.
All of this is for adding new repository schemes without having the rest of the program to be modified: it would unknowingly deal with the specialized instance as if it is a Repository instance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
new
构建构建器。您想要一些其他方法来实际返回构建的对象。这是一个例子:
在这里,构建器和构建的对象是不同的。建造者是一个
真实的对象,带有参数,可以定制构建
对象视情况而定。然后,“构建”的对象是
仅返回方法的值。这允许您构建其他
建设者根据情况而定。 (建造者的问题
功能的一个缺点是它们非常不灵活——很难教它们
一个新的特殊情况。构建器对象仍然存在这个问题,
但至少你的应用程序可以创建一个子类,实例化它,
并将这个对象传递给任何需要创建对象的东西。但
在这种情况下,依赖注入是更好的方法。)
此外,您构建的存储库不需要继承
任何东西,它们只需要一个标签来表明它们是存储库。
这就是我们的
Repository
角色的作用。 (您需要添加此处的 API 代码以及应重用的任何方法。但要小心
关于强制重用——您确定所有标记有
存储库角色会想要那个代码吗?如果没有,只需将代码放入
另一个角色并将其应用于需要该角色的类
功能。)
以下是我们如何使用我们创建的构建器。如果你不想
触摸网络:
但是如果您这样做:
现在您已经有了一个可以按照您喜欢的方式构建对象的构建器,
您只需要在其他代码中使用这些对象即可。所以最后一块
谜题中指的是其他中的“任何”类型的存储库对象
代码。很简单,您使用
does
而不是isa
:就完成了。
new
builds the builder. You want some other method to actually return the built object.Here's an example:
Here, the builder and the built object are distinct. The builder is a
real object, complete with parameters, that can be customized to build
objects as the situation demands. Then, the "built" objects are
merely return values of a method. This allows you to build other
builders depending on the situation. (A problem with builder
functions is that they are very inflexible -- it's hard to teach them
a new special case. This problem still exists with a builder object,
but at least your application can create a subclass, instantiate it,
and pass this object to anything that needs to create objects. But
dependency injection is a better approach in this case.)
Also, there is no need for the repositories you build to inherit from
anything, they just need a tag indicating that they are repositories.
And that's what our
Repository
role does. (You will want to add theAPI code here, and any methods that should be reused. But be careful
about forcing reuse -- are you sure everything tagged with the
Repository role will want that code? If not, just put the code in
another role and apply that one to the classes that require that
functionality.)
Here's how we use the builder we created. If, say, you don't want to
touch the network:
But if you do:
Now that you have a builder that builds the objects the way you like,
you just need to use these objects in other code. So the last piece
in the puzzle is referring to "any" type of Repository object in other
code. That's simple, you use
does
instead ofisa
:And you're done.
不(不直接)。一般来说,在 Moose 中,调用 CLASS->new ,其中 CLASS 是 Moose::Object 将返回 CLASS 的实例。
您能否更详细地描述您想要实现的目标,以及为什么您认为这是您想要的?您可能想要构建一个工厂类——当您调用它的方法时,它将调用适当的类的构造函数并将该对象返回给您,而无需关心您所使用的特定类型。回来:
No (not directly). In general in Moose, calling
CLASS->new
where CLASS isa Moose::Object will return an instance of CLASS.Can you describe in more detail what you are trying to achieve, and why you think this is what you want? You probably want to build a factory class -- when you call a method on it, it will call the appropriate class's constructor and return that object to you, without you having to be concerned with the particular type you get back: