Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 带有泛型的抽象工厂设计模式:额外的解耦在哪里? 这个问题。_Generics_Design Patterns_Decoupling_Abstract Factory - Fatal编程技术网

Generics 带有泛型的抽象工厂设计模式:额外的解耦在哪里? 这个问题。

Generics 带有泛型的抽象工厂设计模式:额外的解耦在哪里? 这个问题。,generics,design-patterns,decoupling,abstract-factory,Generics,Design Patterns,Decoupling,Abstract Factory,我正在尝试尽可能地解耦实现和接口/抽象类,以便能够轻松地切换实现 我学到了依赖注入的方法,但在使用整个框架之前,我想实现/理解该机制 我还了解到实现依赖注入的一种方法是使用抽象工厂 我试图在下面的代码中使用它们,但我看不到在客户机和实现之间有更多的解耦。我想我可能没有正确理解/实施工厂设计模式来解决这个问题 样本情况 假设我有: 作为通用接口的映射器: 公共接口映射器 在这方面: 我希望能够做到的是: 我希望能够主要做到这一点(我的客户): Mapper=GenericMapperFacto

我正在尝试尽可能地解耦实现和接口/抽象类,以便能够轻松地切换实现

我学到了依赖注入的方法,但在使用整个框架之前,我想实现/理解该机制

我还了解到实现依赖注入的一种方法是使用抽象工厂

我试图在下面的代码中使用它们,但我看不到在客户机和实现之间有更多的解耦。我想我可能没有正确理解/实施工厂设计模式来解决这个问题

样本情况 假设我有:

  • 作为通用接口的映射器:

    公共接口映射器

    在这方面:

    我希望能够做到的是: 我希望能够主要做到这一点(我的客户):

    Mapper=GenericMapperFactory.getMapper()
    这将自动交付一个JsonMapper

    我也可以做类似的事情
    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...
         }
    }