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

哪一种更有利?为什么?

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


当前回答

工厂:用于创建对象的实例,其中对象的依赖项完全由工厂保存。对于抽象工厂模式,通常有许多相同抽象工厂的具体实现。工厂的正确实现是通过依赖注入注入的。

生成器:用于构建不可变对象,当要实例化的对象的依赖项部分是预先知道的,部分是由生成器的客户端提供的。

其他回答

构建模式强调创建对象的复杂性(通过“步骤”解决)

抽象模式强调(多个但相关的)对象的“抽象”。

与工厂模式相比,构建器模式的主要优势在于,如果您希望创建一些具有大量可能自定义的标准对象,但最终通常只能自定义少数对象。

例如,如果你想写一个HTTP客户端,你将设置一些默认参数,比如默认的写/读超时、协议、缓存、DNS、拦截器等。

客户端的大多数用户将只使用这些默认参数,而其他一些用户可能希望自定义一些其他参数。在某些情况下,您只需要更改超时并按原样使用其余部分,而在其他情况下,可能需要自定义例如缓存。

以下是实例化客户端的可能方法(取自OkHttpClient):

//just give me the default stuff
HttpClient.Builder().build()   

//I want to use custom cache
HttpClient.Builder().cache(MyCache()).build() 

//I want custom connection timeout
HttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).build() 

//I am more interested in read/write timeout
HttpClient.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS).build()

如果你使用一个工厂模式,你最终会写出很多方法,包括所有可能的创造参数组合。对于构建器,您只需指定您关心的参数,并让构建器为您构建它,同时考虑所有其他参数。

它们之间的主要区别在于,生成器模式主要描述一步一步创建复杂对象。在抽象工厂模式中,重点是对象系列产品。生成器在最后一步返回产品。在抽象工厂模式中,产品立即可用。

例子:假设我们正在创建迷宫

1.抽象工厂:

Maze* MazeGame::CreateMaze (MazeFactory& factory) {
Maze* maze = factory.MakeMaze(); /// product is available at start!!
 /* Call some methods on maze */
return maze;
}

2.建造商:

Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.buildMaze(); /// We don't have access to maze
 /* Call some methods on builder */
return builder.GetMaze();
}

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

假设我们有一辆车

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则逐个构建。

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

工厂:用于创建对象的实例,其中对象的依赖项完全由工厂保存。对于抽象工厂模式,通常有许多相同抽象工厂的具体实现。工厂的正确实现是通过依赖注入注入的。

生成器:用于构建不可变对象,当要实例化的对象的依赖项部分是预先知道的,部分是由生成器的客户端提供的。