Builder设计模式和Factory设计模式之间的区别是什么?

哪一种更有利?为什么?

如果我想测试和比较/对比这些模式,我如何将我的发现表示为图表?


当前回答

生成器和抽象工厂有着不同的目的。根据正确的用例,您必须选择合适的设计模式。

生成器的显著特点:

生成器模式使用简单对象和分步方法构建复杂对象生成器类逐步构建最终对象。此生成器独立于其他对象在这种情况下替换为Factory方法/抽象工厂:从客户端程序传递给Factory类的参数太多,容易出错某些参数可能是可选的,不像工厂中强制发送所有参数

工厂(简单工厂)的显著特点:

创建型模式基于继承Factory返回一个Factory方法(接口),然后返回具体对象您可以用新的具体对象替换接口,客户端(调用者)不应该知道所有具体实现客户端始终只访问接口,您可以在Factory方法中隐藏对象创建详细信息。

通常,设计从使用工厂方法(不那么复杂,更可定制,子类激增)开始,并向抽象工厂、原型或生成器(更灵活,更复杂)发展

查看相关帖子:

将生成器保持在单独的类中(流畅的接口)

设计模式:工厂vs工厂方法vs抽象工厂

有关详细信息,请参阅以下文章:

资源制造

日志记录设备

其他回答

许多设计从使用工厂方法开始(不太复杂,通过子类更可定制),并向抽象工厂、原型或生成器(更灵活,但更复杂)发展。

Builder专注于逐步构建复杂对象。

实施:

明确定义构建所有可用产品表示的通用构建步骤。否则,您将无法继续实现该模式。在基本生成器接口中声明这些步骤。为每个产品表示创建一个具体的生成器类,并实现它们的构造步骤。

抽象工厂专门创建相关对象的族。Abstract Factory会立即返回产品,而Builder允许您在获取产品之前运行一些额外的构建步骤。

您可以将抽象工厂与Bridge一起使用。当Bridge定义的某些抽象只能用于特定实现时,这种配对非常有用。在这种情况下,抽象工厂可以封装这些关系,并从客户端代码中隐藏复杂性。

深入设计模式

我可以看出建筑商和工厂之间的一个显著区别是

假设我们有一辆车

class Car
{
  bool HasGPS;
  bool IsCityCar;
  bool IsSportsCar;
  int   Cylenders;
  int Seats;

  public:
     void Car(bool hasGPs=false,bool IsCityCar=false,bool IsSportsCar=false, int Cylender=2, int Seats=4);
 };

在上面的界面中,我们可以通过以下方式获取汽车:

 int main()
 {
    BadCar = new Car(false,false,true,4,4);
  }

但是如果在创建Seats时发生了一些异常呢???你根本得不到这个物体//但是

假设您有如下实现

class Car
 {
    bool mHasGPS;
    bool mIsCityCar;
    bool mIsSportsCar;
    int mCylenders;
    int mSeats;

 public:
    void Car() : mHasGPs(false), mIsCityCar(false), mIsSportsCar(false), mCylender(2), mSeats(4) {}
    void SetGPS(bool hasGPs=false)  {mHasGPs = hasGPs;}
    void SetCity(bool CityCar)  {mIsCityCar = CityCar;}
    void SetSports(bool SportsCar)  {mIsSportsCar = SportsCar;}
    void SetCylender(int Cylender)  {mCylenders = Cylender;}    
    void SetSeats(int seat) {mSeats = seat;}    
};

 class CarBuilder 
 {
    Car* mCar;
public:
        CarBuilder():mCar(NULL) {   mCar* = new Car();  }
        ~CarBuilder()   {   if(mCar)    {   delete mCar;    }
        Car* GetCar()   {   return mCar; mCar=new Car();    }
        CarBuilder* SetSeats(int n) {   mCar->SetSeats(n); return this; }
        CarBuilder* SetCylender(int n)  {   mCar->SetCylender(n); return this;  }
        CarBuilder* SetSports(bool val) {   mCar->SetSports(val); return this;  }
        CarBuilder* SetCity(bool val)   {   mCar->SetCity(val); return this;    }
        CarBuilder* SetGPS(bool val)    {   mCar->SetGPS(val); return this; }
}

现在您可以这样创建

 int main()
 {
   CarBuilder* bp =new CarBuilder;
    Car* NewCar  = bp->SetSeats(4)->SetSports(4)->SetCity(ture)->SetGPS(false)->SetSports(true)->GetCar();

     bp->SetSeats(2);

     bp->SetSports(4);

     bp->SetCity(ture);

     bp->SetSports(true)

     Car* Car_II=  bp->GetCar();

  }

在第二种情况下,即使一次操作失败,你仍然可以得到汽车。

可能是这辆车后来不太好用了,但你会有目标的。

因为Factory方法在一次调用中为您提供Car,而Builder则逐个构建。

尽管如此,这取决于哪一位的需要。

生成器模式和工厂模式看起来都很像肉眼,因为它们都为您创建对象。

但你需要仔细观察

这个现实生活中的例子将使两者之间的区别更加明显。

假设你去了一家快餐店,点了食物。

1) 什么食物?

披萨

2) 什么浇头?

辣椒,番茄,烤鸡,无菠萝

因此,不同种类的食物是通过工厂模式制作的,但特定食物的不同变体(口味)是通过构建模式制作的。

不同种类的食物

披萨、汉堡、意大利面

披萨的变体

只有奶酪、奶酪+番茄+辣椒、奶酪+西红柿等。

代码示例

您可以在这里看到这两种模式的示例代码实现生成器模式工厂模式

工厂模式允许您一次创建一个对象,而生成器模式允许您中断对象的创建过程。这样,您可以在创建对象期间添加不同的功能。

生成器和抽象工厂生成器设计模式在某种程度上与抽象工厂模式非常相似。这就是为什么在使用其中一种或另一种情况时,能够区分不同的情况是很重要的。在抽象工厂的情况下,客户端使用工厂的方法来创建自己的对象。在Builder的例子中,Builder类被指示如何创建对象,然后被要求创建对象,但是类的组合方式取决于Builder类,这一细节决定了两种模式之间的区别。产品通用接口在实践中,由混凝土建设者创建的产品具有明显不同的结构,因此如果没有理由派生不同的产品,则生成一个公共的父类。这也将生成器模式与抽象工厂模式区分开来,抽象工厂模式创建从公共类型派生的对象。

发件人:http://www.oodesign.com/builder-pattern.html