C# 使用工厂模式保存数据?

C# 使用工厂模式保存数据?,c#,design-patterns,dependency-injection,factory-pattern,strategy-pattern,C#,Design Patterns,Dependency Injection,Factory Pattern,Strategy Pattern,我越来越熟悉工厂模式(以及战略模式),以及该模式可以带来的巨大好处。然而,我一直在与以下情况作斗争: 以前,我会做如下的事情,其中有一个经理类,将建立和保存一辆汽车。这里没有依赖注入,而且实现很差,尤其是在尝试单元测试时 public class CarManager { public static Car GetCarFromDatabase(int carId) { return new Car(); } public static void SaveCar(Car car

我越来越熟悉工厂模式(以及战略模式),以及该模式可以带来的巨大好处。然而,我一直在与以下情况作斗争:

以前,我会做如下的事情,其中有一个经理类,将建立和保存一辆汽车。这里没有依赖注入,而且实现很差,尤其是在尝试单元测试时

public class CarManager
{
    public static Car GetCarFromDatabase(int carId) { return new Car(); }

    public static void SaveCar(Car car) { }
}
我现在明白了,无论是从数据库还是任何地方,我都可以拥有不同的
工厂为我制造汽车!这太棒了!下面是我的问题:

Q1:我的理解是工厂应该只构建对象,对吗?如果是,那么我的第二个问题呢


问题2:如果我按照工厂模式构建对象,我应该如何保存对象?是否有不同的模式,或者我没有完全理解工厂模式?

工厂不应该保存数据。数据访问对象(DAO)或表映射器是一个更好的主意。

该模式应该有助于创建对象。这就是为什么它被归类为“创建”模式的原因。要回答第一个问题,不应将其用于持久化对象

是一种持久性模式,应该用于将对象保存到某个持久性机制或从持久性机制检索数据。根据Martin Fowler的说法,这实际上是一种企业模式,应该与典型的设计模式不同


在思考您的问题时,您希望了解以下情况:哪些状态表示一个类应该有一个单独的责任,这意味着它应该有一个单独的理由进行更改。在本例中,当谈到创建对象并保存(持久化)对象时,您有一个类需要更改,原因有两个。现在,它看起来可能是一个单一的职责,因为存储库可以检索对象并将其保存到应用程序中,并且检索可以看起来像工厂(通常是存储库中的工厂对象),但在您描述的内容中,对象的职责太多了。

一般来说,我认为你从错误的角度来看待这个问题

您需要确定您试图解决的问题,然后寻找适合该问题的解决方案。在我看来,这更像是你发现了某种模式,然后试图将其应用于你遇到的每一个问题


您在发布的代码中提到的唯一问题是单元测试不容易。使类更易于测试的一个解决方案是反转它们的依赖关系。因此,我将开始研究这个类所依赖的其他类,并开始创建这些可注入依赖项。作为一个起点,我建议您仔细阅读依赖项反转/控制反转。

Q1-是的,工厂模式应该是创建对象的理想方式。因此,可以使用factory图案创建汽车对象


Q2-为了保存汽车对象,不应使用factory模式。解耦汽车对象创建和保存汽车对象。而且,如果不准确理解需求,就很难提出一种设计模式来保存汽车对象。在我看来,如果您只需要保存汽车对象,那么您可能只需要在汽车管理器类中使用一个save方法。不要过度使用设计模式。

所有这些都取决于您的需要和您想如何做,模式是实践,没有标准,它们鼓励代码重用,模式不是一成不变的。那么,为什么不使用Factory模式使对象持久化呢?。这就是我如何使用这种模式来解决从不同数据库读取/写入数据的问题,也许这不是使用该模式的更好形式,但它目前正在工作,可扩展,分布在各个层中,几乎每个人都能理解:

namespace Domain.App
{
    public class PresentationClass
    {
        private Collection<ISomeOutput> GetData(ISomeInput1 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier );
            return logic.GetSomeData(input) as Collection<ISomeOutput>;
        }
        private IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier);
            return logic.ExecuteSomeAction(input);
        }
    }
}   

namespace Domain.Logic
{
    public sealed class ServicesLogicContext : ServicesLogicContextBase
    {
        public IList<ISomeOutput> GetSomeData(ISomeInput1 input) 
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            return DBServicesProvider.GetSomeData(input);
        }
        public IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            IMethodResult result = services.ExecuteSomeAction(input);
            return result;
        }
    }
}

namespace Domain.Data
{
    public abstract class DBServices : IServices
    {
        public virtual IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public virtual IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific1 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific2 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public sealed class DBServicesProvider
    {
        public static DBServices CreateServices(MyType identifier)
        {
            DBServices result = null;       
            switch(identifier) 
            {
                case MyType.Specific1: result = new DBServicesSpecific1(); break;
                case MyType.Specific2: result = new DBServicesSpecific2(); break;       
            }
            return result;
        }
    }
}
namespace-Domain.App
{
公共类PresentationClass
{
私有集合GetData(ISomeInput1输入)
{   
ServicesLogicContext逻辑=新的ServicesLogicContext((MyType)标识符);
返回逻辑。GetSomeData(输入)作为集合;
}
私有IMethodResult ExecuteSomeAction(ISomeInput2输入)
{   
ServicesLogicContext逻辑=新的ServicesLogicContext((MyType)标识符);
返回逻辑。执行测量操作(输入);
}
}
}   
名称空间域逻辑
{
公共密封类ServicesLogicContext:ServicesLogicContextBase
{
公共IList GetSomeData(ISomeInput1输入)
{
DBServices services=dbserviceprovider.CreateServices(SomeIdentifier);
返回DBServicesProvider.GetSomeData(输入);
}
公共IMethodResult ExecuteSomeAction(ISomeInput2输入)
{
DBServices services=dbserviceprovider.CreateServices(SomeIdentifier);
IMethodResult=services.ExecuteSomeAction(输入);
返回结果;
}
}
}
命名空间域.Data
{
公共抽象类DBServices:IServices
{
公共虚拟IList GetSomeData(ISomeInput1输入){…}
公共虚拟IMethodResult ExecuteSomeAction(ISomeInput2输入){…}
}
公共类DBServicesSpecific1:DBServices
{
公共重写IList GetSomeData(ISomeInput1输入){…}
公共重写IMethodResult ExecuteSomeAction(ISomeInput2输入){…}
}
公共类DBServicesSpecific2:DBServices
{
公共重写IList GetSomeData(ISomeInput1输入){…}
公共重写IMethodResult ExecuteSomeAction(ISomeInput2输入){…}
}
公共密封类DBServicesProvider
{
公共静态DBServices CreateServices(MyType标识符)
{
DBServices result=null;