转载:http://www.linxh.blog.chinaunix.net/uid-29140694-id-4105980.html
建造者模式:将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建出不同的表示。
举例:
假设KFC推出两种套餐:奥尔良鸡腿堡套餐和香辣鸡腿堡套餐。
奥尔良套餐包括:一个奥尔良鸡腿堡、一个炸鸡翅、一杯雪碧。
鸡腿堡套餐包括:一个香辣鸡腿堡、一份薯条、一杯可乐。
每份套餐都是:主食、副食、饮料。
KFC服务员要根据顾客的要求来提供套餐,那这个需求里面什么是固定的,什么是变化的呢?很明显顾客都是要的套餐,顾客的目的是一样的。 套餐里面都是主食、副食、饮料,这也是固定的。至于主食是什么、副食是什么、饮料是什么这个是变化的。
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成,由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将他们组合在一起的算法却相对稳定。当遇到这种场景时,你就可以考虑能否用建造者模式实现了。
下面我们用一个例子描述下建造者模式的代码实现过程。
包括:
产品类Product
产品子类
构造者接口IBuilder
具体构造者类
执行类
/**
* 建造者模式(Builder)
* 包括:
* 产品类Product
* 产品子类
* 构造者接口IBuilder
* 具体构造者类
* 执行类
*
*/
//产品类:House
class House {
//零件
private String door;
private String floor;
private String wall;
private String windows;
//getter/setter
public String getDoor() {
return door;
}
public void setDoor(String door) {
this.door = door;
}
public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getWindows() {
return windows;
}
public void setWindows(String windows) {
this.windows = windows;
}
}
//产品子类:ChinaStyleHouse、BritishStyleHouse
class ChinaStyleHouse extends House {
//中式房屋
//do someting here
}
class BritishStyleHouse extends House {
//欧式房屋
//do something here
}
//房屋构造者接口:IHouseBuilder
interface IHouseBuilder {
//建造各零件
public void buildDoor();
public void buildFloor();
public void buildWall();
public void buildWindows();
//返回建造完的对象
public House getHouse();
}
//具体建造者类:ChinaStyleHouseBuilderImpl、BritishStyleHouseBuilderImpl
class ChinaStyleHouseBuilderImpl implements IHouseBuilder {
public House house = new ChinaStyleHouse();
@Override
public void buildDoor() {
house.setDoor("中式风格房门");
}
@Override
public void buildFloor() {
house.setFloor("中式风格地板");
}
@Override
public void buildWall() {
house.setWall("中式风格墙壁");
}
@Override
public void buildWindows() {
house.setWindows("中式风格门窗");
}
@Override
public House getHouse() {
return house;
}
}
class BritishStyleHouseBuilderImpl implements IHouseBuilder {
public House house = new BritishStyleHouse();
@Override
public void buildDoor() {
house.setDoor("英式风格门");
}
@Override
public void buildFloor() {
house.setFloor("英式风格地板");
}
@Override
public void buildWall() {
house.setWall("英式风格墙壁");
}
@Override
public void buildWindows() {
house.setWindows("英式风格窗户");
}
@Override
public House getHouse() {
return house;
}
}
//执行者:HouseDirector
class HouseDirector {
//建造房子
public House buildHouse(IHouseBuilder builder) {
//建造各个组成部分
builder.buildDoor();
builder.buildFloor();
builder.buildWall();
builder.buildWindows();
//返回建造完的房子
return builder.getHouse();
}
}
public class BuilderTest {
public static void main(String[] args) {
//假设现在我下需要一个中式房屋的对象
IHouseBuilder cbuilder = new ChinaStyleHouseBuilderImpl();
House chinaHouse = new HouseDirector().buildHouse(cbuilder);
System.out.println("------------------------------");
System.out.println("房门属性:" + chinaHouse.getDoor());
System.out.println("墙壁属性:" + chinaHouse.getWall());
System.out.println("天花板属性:" + chinaHouse.getFloor());
System.out.println("窗户属性:" + chinaHouse.getWindows());
System.out.println("------------------------------");
//假设现在我下需要一个英式房屋的对象
IHouseBuilder bbuilder = new BritishStyleHouseBuilderImpl();
House birtishHouse = new HouseDirector().buildHouse(bbuilder);
System.out.println("------------------------------");
System.out.println("房门属性:" + birtishHouse.getDoor());
System.out.println("墙壁属性:" + birtishHouse.getWall());
System.out.println("天花板属性:" + birtishHouse.getFloor());
System.out.println("窗户属性:" + birtishHouse.getWindows());
System.out.println("------------------------------");
}
}
建造者模式的优点
(1)使用建造者模式可以使客户端不必知道产品内部组成的细节。
(2)具体的建造者类之间是相互独立的,对系统的扩展非常有利。
(3)由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。