Generics 带有泛型的抽象工厂设计模式:额外的解耦在哪里? 这个问题。
我正在尝试尽可能地解耦实现和接口/抽象类,以便能够轻松地切换实现 我学到了依赖注入的方法,但在使用整个框架之前,我想实现/理解该机制 我还了解到实现依赖注入的一种方法是使用抽象工厂 我试图在下面的代码中使用它们,但我看不到在客户机和实现之间有更多的解耦。我想我可能没有正确理解/实施工厂设计模式来解决这个问题 样本情况 假设我有:Generics 带有泛型的抽象工厂设计模式:额外的解耦在哪里? 这个问题。,generics,design-patterns,decoupling,abstract-factory,Generics,Design Patterns,Decoupling,Abstract Factory,我正在尝试尽可能地解耦实现和接口/抽象类,以便能够轻松地切换实现 我学到了依赖注入的方法,但在使用整个框架之前,我想实现/理解该机制 我还了解到实现依赖注入的一种方法是使用抽象工厂 我试图在下面的代码中使用它们,但我看不到在客户机和实现之间有更多的解耦。我想我可能没有正确理解/实施工厂设计模式来解决这个问题 样本情况 假设我有: 作为通用接口的映射器: 公共接口映射器 在这方面: 我希望能够做到的是: 我希望能够主要做到这一点(我的客户): Mapper=GenericMapperFacto
- 作为通用接口的映射器:
公共接口映射器 在这方面: 我希望能够做到的是: 我希望能够主要做到这一点(我的客户):
这将自动交付一个JsonMapper 我也可以做类似的事情Mapper=GenericMapperFactory.getMapper()
并获取正确的具体对象 免责声明 我希望我的问题是明确的,如果没有,请毫不犹豫地告诉我,这样我就可以继续努力。这些概念对我来说还不完全清楚,所以我很难写出清晰的问题 提前感谢你的帮助。Mapper=GenericMapperFactory.getMapper()
最好的是Antonin,关键不是是否使用工厂,而是应该使用依赖项注入和一些反转控制容器。因此,您的存储库实例化将由整个容器完成,您的代码对实现来说是绝对不可知的 否则,如果您进行手动依赖项注入,显然需要手动实例化实现 例如,使用具有依赖项注入支持的反转控制容器,可以注入存储库,还可以自动获取映射器的工厂或抽象映射器:public class WhoKnows { public WhoKnows(IOnlineRepository repo) { // repo will come up with its dependencies already loaded // and its dependencies will also have their own dependencies already // loaded in cascade... } }
实例化具体对象与创建的类耦合的位置。这是你的主要问题。通过使用工厂模式,可以将main与接口映射器的实现分离。你只知道那家工厂。现在再次对映射器进行子类化并使用另一种映射器不会影响主方法 为了保护主实现类不受影响,我不推荐工厂模式。Main是程序启动的地方,因此负责创建一些对象并将它们组合在一起以引导应用程序 当您在应用程序中动态创建对象时,或者当您使用一些被设置为一起使用的对象时,应该使用工厂(例如:窗口工厂(GUI))
例如,如果您创建的应用程序可以使用Qt或Cocoa GUI运行,那么您必须确保框架之间的一致性。QtFactory将创建QWidget和表单,而CocoaFactory将创建CocoaWindows。应用程序的其余部分与使用的框架分离。如果您主要安装一个QtFactory,那么您的程序将使用一个Qt GUI运行,使用CocoaFactory,它将是一个Cocoa GUI。这是抽象的工厂模式。它允许您交换实现类,而不必担心它们是否会混合(Cocoa窗口和QWidget)。谢谢@Matías_Fidemraizer,但我认为抽象工厂设计模式是实现依赖注入的一种方式。我认为有了这种设计模式,我就能够将接口和实现之间的关系集中在一个单独的类中,这是没有问题的。其实IoC集装箱有内部工厂,对吧。。。也许我根本不明白你的问题。。。当您谈到抽象工厂时,您是在尝试实现一个工厂,以将实现类型化为接口/抽象类,还是一个映射器的抽象工厂?目标是消除客户机和实现之间的强依赖性(即repo或main和JsonMapper之间),并将其隔离到其他地方,以便我可以轻松切换实现。我会尝试修正我的问题,让它更清楚(事实上,这在我的头脑中并不清楚,因此问题不清楚)。@Antonin顺便说一句,我看到你在试图重新发明轮子,不是吗?使用IoC容器,您无法处理实现IoC容器的复杂性并在短时间内获得类似的结果。。。main{ JsonMapper mapper = new JsonMapper(); // reference to concrete JsonMapper OnlineRepo repo = new OnlineRepo(mapper); // inject concrete JsonMapper }
public class WhoKnows { public WhoKnows(IOnlineRepository repo) { // repo will come up with its dependencies already loaded // and its dependencies will also have their own dependencies already // loaded in cascade... } }