builder 模式

本文详细介绍了Builder模式,将复杂对象的构建与表示分离,隐藏对象构造细节。与抽象工厂模式有微妙差异。还给出建造房屋的示例,客户通过Director构建不同类型房屋,屏蔽了房屋创建细节,提供了C#代码实现。

第一眼看到builder模式,就觉得眼熟,和我们前面将的抽象工厂模式非常相近,我想不可能相同的模式用两个不同的名字,于是就有了下面的一些火花了.

Builder模式定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

这个翻译就很模糊,看了,跟没看一样,可是这是网上目前最多的翻译了,所以也不想去理解他了,反正心里希望翻译这句话的人一路走好.所以说那些翻译国外文章的人一定要注意了,如果你们自己都没弄懂的话,千万不要翻出来,害大家.

下面用原文来表述吧:

The Builder pattern allows a client object to construct a complex object by specifying only its type and content. The client is shielded from the details of the object’s construction.(简述:隐藏了对象构造的细节)

It is a pattern for step-by-step creation of a complex object so that the same construction process can create different representations is the routine in the builder pattern that also makes for finer control over the construction process. All the different builders generally inherit from an abstract builder class that declares the general functions to be used by the director to let the builder create the product in parts.

Builder has a similar motivation to the abstract factory but, whereas in that pattern, the client uses the abstract factory class methods to create its own object, in Builder the client instructs the builder class on how to create the object and then asks it for the result. How the class is put together is up to the Builder class. It's a subtle difference.

The Builder pattern is applicable when the algorithm for creating a complex object should be independent of the parts that make up the object and how they are assembled and the construction process must allow different representations for the object that’s constructed

Example

Below is an example of creating a House, the clients asks the Director (CDirector class) to create a House by calling BuildHouse method which takes a boolean parameter (blnBackyard), the director then creates an Apartment (Concrete Builder) if the blnBackyard is false or a Single Family Home (Concrete Builder) if the blnBackyard is true (both of them implements IHouse interface) and returns IHouse (Abstract Builder) Interface.(下面的例子是一个建造房屋的例子,客户用 buildhouse(Boolean blnbackyard) 来建造房屋,

The director does the complex building of a House and the client gets back IHouse interface that it codes against without worrying about the creation of House, Rooms, backyard etc.

 

C#

using System;
using System.Collections;

public interface Ihouse//房子的接口
{
   bool GetBackyard();//取得后院的引用
   long NoOfRooms();//房子数
   string  Discription();//房子的描述
}

public class CApt:Ihouse//没有后院的房子
{   private bool mblnBackyard;
   private Hashtable Rooms;
   public CApt()//
   {   CRoom room;
      Rooms = new Hashtable();
      room = new CRoom();
      room.RoomName = "Master Bedroom";
      Rooms.Add ("room1",room);

      room = new CRoom();
        room.RoomName = "Second Bedroom";
      Rooms.Add ("room2",room);

      room = new CRoom();
      room.RoomName = "Living Room";
      Rooms.Add ("room3",room);
     
      mblnBackyard = false;//关键,没有后院.
   }

   public bool GetBackyard()
   {
      return mblnBackyard;
   }
   public long NoOfRooms()
   {
      return Rooms.Count;
   }
   public string  Discription()
   {
      IDictionaryEnumerator myEnumerator  =
                      Rooms.GetEnumerator();
        string strDiscription;
        strDiscription = "This is an Apartment with " +
                         Rooms.Count + " Rooms /n";
        strDiscription = strDiscription +
             "This Apartment doesn't have a backyard /n";
      while (myEnumerator.MoveNext())
      {
         strDiscription = strDiscription + "/n" +
                 myEnumerator.Key + "/t" +
                 ((CRoom)myEnumerator.Value).RoomName;
      }
        return strDiscription;
   }
}

public class CSFH:IHouse
{   private bool mblnBackyard;
   private Hashtable Rooms;
   public CSFH()
   {
      CRoom room;
      Rooms = new Hashtable();

      room = new CRoom();
      room.RoomName = "Master Bedroom";
      Rooms.Add ("room1",room);

      room = new CRoom();
      room.RoomName = "Second Bedroom";
      Rooms.Add ("room2",room);

      room = new CRoom();
      room.RoomName = "Third Room";
      Rooms.Add ("room3",room);
     
      room = new CRoom();
      room.RoomName = "Living Room";
      Rooms.Add ("room4",room);

      room = new CRoom();
      room.RoomName = "Guest Room";
      Rooms.Add ("room5",room);

      mblnBackyard = true;//有后院
 
   }

   public bool GetBackyard()
   {
      return mblnBackyard;
   }
   public long NoOfRooms()
   {
      return Rooms.Count;
   }
   public string  Discription()
   {
     IDictionaryEnumerator myEnumerator  =
                         Rooms.GetEnumerator();
     string strDiscription;
     strDiscription = "This is an Single Family Home with "
                      + Rooms.Count + " Rooms /n";
     strDiscription = strDiscription +
                          "This house has a backyard /n";
       while (myEnumerator.MoveNext())
     {
        strDiscription = strDiscription +
                "/n" + myEnumerator.Key + "/t" +
                ((CRoom)myEnumerator.Value).RoomName;
     }     
     return strDiscription;
   }
}

public interface Iroom//房间接口.
{
   string RoomName{get;set;}
}

public class CRoom:IRoom
{
   private string mstrRoomName;
   public string RoomName
   {
      get
      {
         return mstrRoomName;
      }
      set
      {
         mstrRoomName = value;
      }
   }
}

public class CDirector
{
   public IHouse BuildHouse(bool blnBackyard)//返回不同的房子的.builder,director来总体控制用什么builder来造.
   {
      if (blnBackyard)
      {
         return new CSFH();//造有后院的房子
      }
      else
      {
         return new CApt(); //造没有后院的房子
      }
   }
}

public class Client
{
  static void Main(string[] args)
  {
    CDirector objDirector = new CDirector();
    IHouse objHouse;
    objHouse = objDirector.BuildHouse(bool.Parse(args[0]));
    Console.WriteLine(objHouse.Discription());
  }
}
 


 

### Builder模式的使用与实现 Builder模式是一种用于构建复杂对象的设计模式,其主要目的是通过逐步设置对象的属性来简化对象的创建过程。这种方式不仅提高了代码的可读性,还隐藏了对象创建的复杂性。 在Java中,Builder模式通常通过以下方式实现: 1. **定义一个包含必要参数的构造函数**:Builder类的构造函数接受对象的核心属性作为参数[^2]。 2. **提供链式调用的方法**:每个设置方法返回Builder对象本身,从而允许将多个设置方法链接在一起[^5]。 3. **创建最终对象**:通过`build()`方法返回构建完成的对象实例[^4]。 以下是一个典型的Builder模式实现示例: ```java // 被构建的复杂对象 public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int sodium; private final int carbohydrates; // 私有构造函数,只能通过Builder创建 private NutritionFacts(Builder builder) { this.servingSize = builder.servingSize; this.servings = builder.servings; this.calories = builder.calories; this.sodium = builder.sodium; this.carbohydrates = builder.carbohydrates; } // Getter 方法 public int getServingSize() { return servingSize; } public int getServings() { return servings; } public int getCalories() { return calories; } public int getSodium() { return sodium; } public int getCarbohydrates() { return carbohydrates; } // 静态内部类 Builder public static class Builder { private final int servingSize; private final int servings; private int calories = 0; private int sodium = 0; private int carbohydrates = 0; // 必要参数的构造函数 public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } // 设置可选参数的方法,支持链式调用 public Builder calories(int val) { this.calories = val; return this; } public Builder sodium(int val) { this.sodium = val; return this; } public Builder carbohydrates(int val) { this.carbohydrates = val; return this; } // 构建最终对象 public NutritionFacts build() { return new NutritionFacts(this); } } } // 使用示例 NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8) .calories(100) .sodium(35) .carbohydrates(27) .build(); ``` 上述代码展示了如何通过Builder模式构建一个复杂的`NutritionFacts`对象。通过链式调用,可以清晰地设置对象的各个属性。 ### 注意事项 - **必要参数与可选参数**:Builder模式的一个重要特性是区分必要参数和可选参数。必要参数通常在Builder类的构造函数中指定,而可选参数则通过链式调用设置[^2]。 - **不可变对象**:通过私有构造函数和Builder类,可以确保生成的对象是不可变的,从而提高程序的安全性[^4]。 - **适用场景**:当对象的构造需要多步初始化或赋值时,Builder模式尤为适用[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值