设计模式(4)之建造者模式
建造者模式是最复杂的创建型模式,它用于创建一个包含多个组成部分的复杂对象,可以返回一个完整的产品对象给用户,建造者模式关注该复杂对象是如何一步一步创建而成的,对于用户而言,无需知道创建过程和内部组成细节,只需要使用创建好的完整对象即可
复杂对象相当于一辆有待建造的汽车,而对象的属性相当于汽车的部件,建造产品的过程就相当于组装部件的过程。由于组装部件过程很复杂,因此,这些部件的组装过程被“外部化”到一个称作建造者的对象里,建造者返回客户端的是一个建造完成的完整的产品对象,而用户无需关心该对象所包含的属性以及他们的组装方式,这就是建造者模式的模式动机。
将一个复杂对象的构建与他的表示分离,使得同样的构造过程可以创建不同的表示,建造者模式是一步一步创建一个复杂的对象,他允许用户只通过复杂对象的类型和内容就可以创建他们,用户不需要知道内部创建的具体细节。
案例分析:
描述:kfc创建不同的套餐,套餐是一个复杂对象,它一般包含主食(汉堡、鸡肉卷)和饮料(果汁、可乐)等组成部分,不同的套餐有着不同的组成部分,而kfc的服务员可以根据顾客不同的需求,一步一步的装配这些组成部分,构造一个完整的套餐,然后给顾客。
服务员在这里就相当于建造模式中的指挥类角色,调用不同的建造者完成组装过程,然后将产品给用户
伪代码:
//产品类meal(套餐),这个就是复杂产品对象,它包括food和dirnk两个成员属性,其中food表示主食,drink表示饮料,还有getter setter方法
public class Meal
{
private string food;
private string drink;
public void setFood($food)
{
$this->food = $food;
}
public void setDrink($dirnk)
{
$this->dirnk = $dirnk;
}
public void getFood()
{
return $this->food;
}
public void getDrink()
{
return $this->dirnk;
}
}
//抽奖建造者者类MealBuilder(套餐建造者类),它是一个抽象类,生命了抽象的部件组装方法buildFood() 和buildDrink(),MeanBuilder抽象类中还定义了meal类型的对象meal,提供工厂方法getMeal返回meal对象
public abstract class MealBuilder
{
protected $meal = new meal();
public abstract void builderFood();
public abstract void builderDrink();
public meal getMeal()
{
return $this->meal;
}
}
//具体建造者类SubMealBuilderA,(套餐A的创建者),它是抽象类MealBuilder的子类,实现了在抽象父类中声明的builderFood和builderDrink的部件组装方法,该套餐有一个汉堡和一个肌肉卷组成
public class SubMealBUilderA extends MealBuilder
{
public void builderFood()
{
$this->meal->setFood('一个汉堡');
}
public void builderDrink()
{
$this->meal->setDrink('一杯可乐');
}
}
//具体建造者类SubMealBuilderB,用于创建套餐b,由一个鸡肉卷和一杯果汁组成
public class SubMealBUilderB extends MealBuilder
{
public void builderFood()
{
$this->meal->setFood('一个鸡肉卷');
}
public void builderDrink()
{
$this->meal->setDrink('一杯果汁');
}
}
//指挥者类KfcWaiter(kfc服务员),在kfc套餐制作工程中,他就是kfc的服务员,在其中定义了一个抽象建造者类型的变量mb,具体建造着类型由客户端制定,在其construct()方法中调用mb对象的部件组装方法和返回meal对象的工厂方法,用于向客户端返回一个包含主食和饮料的完整套餐。
public class KfcWailter
{
private MealBuilder $mb;
public void setMealBuilder(Mealbuilder $mb)
{
$this->mb = $mb;
}
public Meal construct()
{
$this->mb->builderFood();
$this->mb->builderDrink();
return $this->mb->getMeal();
}
}
MealBuilder $mb = new Config::get('use_builder');//获取具体的建造者类并实例化
kfcWailter $waiter = new KfcWailter();//实例化调用者类
$wailter->setMealBuilder($mb);//为指挥者设置具体建造者类
Meal $meal = $wailter->constrcunt();//组装并且返回
最后总结:
1.建造者模式将一个复杂对象的创建于它的表示分离,这样同样的创建过程可以创建不同的而表示。建造者模式是一步一步的创建一个复杂的对象,它允许用户只通过制定复杂对象的类型和内容就可以创建他们,用户不需要知道内部的具体构建细节,建造者模式属于类创建模式。
2.建造者模式包含如下四个角色:抽象建造者是为具体建造者创建一个产品对象的各个部件指定的抽奖接口,是具体建造者的父类;具体建造者继承抽象建造者,实现父类中各部件的构造和装配方法,定义它创建的复杂对象;产品抉择就是那个药构建的复杂的对象,包含多个部件;指挥者负责安排复杂对象的建造次序,指挥者与抽奖建造者存在关联关系,指挥着面向抽象编程,通过调用具体建造者方法完成复杂对象的构造。
3.在建造者模式中引入了一个指挥者类,该类的作用主要有两个:第一是隔离客户与生产的过程;第二是它复杂产品的创建过程。指挥者只对抽奖编程,客户端只需要知道要构建的复杂对象的类型,即可通过指挥者类调用创建者的相关方法完成产品的构建。
4.建造者模式的主要优点在于客户端不需要知道产品内部具体的创建过程,将产品本身与创建过程解耦,是相同的创建过程可以创建不同的产品,每一个具体的建造者都是相互独立,与其他建造者无关,因此可以在系统中方便的通过替换建造者或者增加具体的建造者来完成需求变更,符合开闭原则,还可以更加精细的控制产品的创建过程;主要缺点是由于建造者模式所创建的产品一般具有较多的共同点,其组成部分形似,因此在使用范围上受到了一定程度的限制,如果产品内部变化过于复杂,那么可能导致需要定义很多建造者类来实现这种变化,从而导致系统变得庞大臃肿 不利于维护.
5.建造者模式使用情况包括:需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性;需要生成的产品对象的属性相互依赖,需要指定其生成顺序,对象的创建过程独立于创建该对象的类;隔离复杂对象的创建和使用,并使得相同的创建过程可以创建出不同的产品对象。