【问题标题】:Factory Pattern Confusion工厂模式混乱
【发布时间】:2012-06-09 21:56:40
【问题描述】:

当客户端应用程序请求一个新对象时, 我让 Factory 类为我创建新对象。

public class CarFactory{

    public Car CreateCar()
    {
       //create a new car object and send back  
    }
}

汽车对象的属性是通过调用存储在数据库中的存储过程来填充的。在数据库中,我们存储可以每天更改的默认值。默认表由外部系统填充。

public class Car {
  public List<string> DefaultTyres {get;set;}
  public List<string> DefaultPetrolSpec {get;set;} 
}

所以当工厂(服务层调用)创建 Car 对象时,工厂类调用存储库类,然后调用 DB 来填充 Car 的属性……但是这些层的关系听起来有点奇怪…… .

public Car CreateCar()
{
    //create a new car object and send back
    //Call CarRepository.GetDefaultTyres(), CarRepository.GetDefaultPetrolSpec() etc.  
}

因为我认为我的工厂实现做了很多工作。可能它不应该调用存储库层(然后调用数据库来获取汽车对象的数据)。

你们怎么看?工厂类应该与数据库通信吗?如果他们这样做可以吗?如果不是,那应该是谁的责任?

【问题讨论】:

  • 这篇文章是否有任何理由被标记在“C#”“Java”“.net”下?
  • @AlexLockwood 尽管我个人更喜欢拼写“Tires”,但“Tyers”在英式英语中是正确的......
  • 谢谢亚历克斯。贝斯卡是正确的。亚历克斯,主要是因为我想引起 OOP 人的注意,我正在使用 Java 应用程序,我猜 C# 人有相似的背景:)
  • 我删除了我之前的评论。感谢您让我知道...我不是来自英国,所以这是我的借口:P。
  • 不用担心,我猜...我只是觉得很有趣,您决定用三种不同的语言标记您的帖子,但没有在“设计模式”或“工厂模式”下标记它" :)

标签: c# java .net oop design-patterns


【解决方案1】:

如果您有一个额外的类来处理实际的数据库连接,我认为这很好。我所说的这样一个类是指执行实际连接、处理一些连接/查询异常等的类。Factory 类不应该知道与 DB 相关的东西,它应该将其委托到另一个类/对象.

数据库的这个抽象层也可以是一个完整的类层次树,而不仅仅是一个类。像这样的:

每个子类都知道如何处理与特定 RDBMS 的连接。

PS:请注意,这只是一个示例,您可能不必这样做。此外,拥有这样的层次结构可能会使事情变得有些复杂,因为您可能还需要为这些类创建一个工厂。

【讨论】:

    【解决方案2】:

    答案取决于是否可能涉及多个(实现)存储库或多个数据库/其他数据存储。如果上面的答案是肯定的(即使此时这只是预期的需要/可能性),最好有一个存储库层,以便在/如果发生这些更改时将 Factory 类与上述更改隔离。

    换个角度想:知道如何制造汽车是工厂类的责任; 它有责任知道连接什么数据库/何时/如何连接。通常最好将职责保持简单以促进变更和模块化设计

    【讨论】:

      【解决方案3】:

      随着时间的推移,我学到的一件事是,您的问题可能有 5 个答案。而且,他们都是对的。真正的问题是:你所做的有意义吗?如果您的工厂在服务器上,并且与数据库的连接最接近那里,那么这就是调用所在的位置。

      现在我有时会问自己和其他人一样的问题。例如,工厂应该在制造汽车时为汽车制造轮胎和汽油,还是应该让汽车自己知道如何制造。

      因此您可能需要考虑这一点:如果您的工厂正在创建大量对象(这通常是您拥有工厂模式的原因),那么您的所有元素都有一个基类/公开 Create 方法的接口。 (我发布了一个非常快速而肮脏的示例,通过反射来创建类型可以使工厂更加通用)

      例子:

         public interface FactoryObject
         {
                void Create();
                void Destroy();
         }
      
         public class Car:FactoryObject
         {
              public void Create()
              {
                   //TODO: Create my tyres and my petrol
                   //TODO: Create my fenders and body
              }
         }
      
         public class Bicycle:FactoryObject
         {
              public void Create()
              {
                   //TODO: Create my tyres but I do not need petrol
                   //TODO: Create my fenders but I have no body
              }
         }
      
         public class Factory
         {
              public FactoryObject GetFactoryObject(Type type)
              {
                   FactoryObject returnedObject = null;
                   if ( type is Car ) returnedObject = new Car();
                   elseif (type is Bicycle) returnedObject = new Bicycle();
                   if (returnedObject != null)
                        returnedObject.Create();
                   return returnedObject;
              }       
         }
      

      以这种方式,您的工厂知道要创建一个 FactoryObject,但是它不知道如何构建该对象。更重要的是它不在乎。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多