您如何在领域驱动设计中使用具有工厂模式的接口?

Posted

技术标签:

【中文标题】您如何在领域驱动设计中使用具有工厂模式的接口?【英文标题】:How do you use Interfaces with the Factory Pattern in Domain-Driven Design? 【发布时间】:2010-09-30 04:53:01 【问题描述】:

默认情况下为您的域对象工厂使用接口是否有意义,或者是否应该只在需要时为工厂类保留接口?

public IUserFactory

    User CreateNewUser();


public UserFactory : IUserFactory

    public User CreateNewUser()
    
        return new User();
    

【问题讨论】:

为什么...?总是这样做有什么好处? 虽然您的示例是用 C# 编写的,但我们没有理由不能用 Java 提出这个设计问题。 是的,我并不想忽略 Java 人员或任何人 【参考方案1】:

从接口创建工厂可以更轻松地使用模拟类对其进行测试,并简化 IoC 应用程序的使用,因此虽然我可能不一定需要它们来实现应用程序功能,但我通常会构建和调用大多数应用程序通过接口类。

如果您不考虑单元测试或 IoC 模式(除了宗教观点),我可能不会打扰。

我发现使用它们的最大痛苦是,至少在 Visual Studio 中,属性或函数上的“转到定义”会跳转到接口定义,而不是类定义。

【讨论】:

你不能使用 moq(例如)从基于非接口的类创建模拟对象吗? 没错,但如果您正在创建自己的功能,因为您需要更好地控制功能,那么通过界面来完成它们总是更好【参考方案2】:

这是同一问题到 Java 的翻译。

原始示例

public interface UserFactoryIF

   User createNewUser();

然后是工厂的实现

public class UserFactory implements UserFactoryIF

     public User createNewUser()
     
         // whatever special logic it takes to make a User
         // below is simplification
         return new User();
     

我认为为工厂定义接口没有什么特别的好处,因为您正在为集中式生产者定义单个接口。通常我发现我需要为同一种产品生产许多不同的实现,而我的工厂需要消耗许多不同类型的参数。也就是说,我们可能有:

public interface User

    public String getName();
    public long getId();
    public long getUUID();
    // more biz methods on the User

工厂看起来像这样:

public class UserFactory 

    public static User createUserFrom(Person person) 
        // ...
        return new UserImpl( ... );
    

    public static user createUserFrom(AmazonUser amazonUser) 
         // ... special logic for AmazonWS user
        return new UserImpl( ... );          
    

    private static class UserImpl implements User 
       // encapsulated impl with validation semantics to
       // insure no one else in the production code can impl
       // this naively with side effects
    

希望这能说明问题。

【讨论】:

【参考方案3】:

在你给出的例子中,我什至不明白你为什么需要去工厂。

工厂模式的本质是 到“定义一个用于创建的接口 一个对象,但让子类 决定要实例化哪个类。这 工厂方法让类延迟 子类的实例化。” - ***

你有不同类型的用户,或者用户本身就是某种类型的东西。可能是你没有把事情说清楚。我们通常在抽象工厂方法模式中使用接口,我们需要处理多个相关对象族。

注意:不要忘记,模式可以帮助我们,但这并不意味着我们必须使用它们,因为它们是可用的,无论我们是否需要它们。

【讨论】:

【参考方案4】:

两件事:(1)我会等到我需要(或看到迫在眉睫的需要)一个替代实现之前我会创建接口和(2)接口几乎总是使单元测试更容易,尤其是在模拟时,所以我经常想出一个界面需求。

【讨论】:

【参考方案5】:

并非所有东西都必须有接口;如果你有一个单一的实现,而没有理由有任何其他的,我看不出为什么要定义一个接口。

【讨论】:

此外,类上的方法签名集合也算作一个接口,这与您是否正在实现 Java/C# 接口无关。

以上是关于您如何在领域驱动设计中使用具有工厂模式的接口?的主要内容,如果未能解决你的问题,请参考以下文章

如何运用领域驱动设计 - 值对象

领域驱动设计和工厂类的作用

浅析 DDD 领域驱动设计

浅析 DDD 领域驱动设计

如何运用领域驱动设计 - 领域服务

领域驱动设计中的层