设计模式(七):建造者模式
一、概念
建造者模式属于创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。类图如下所示:
二、简单实现
建造嘛建造,这边我们就以建造房子为例子,讲一讲是怎么用建造者模式建房子的。假如需求是这样的:需要建造的房子暂时有两种,别墅和公寓。先不考虑设计模式,来实现一番
-
创建House抽象父类(使用了Lombok插件,减少样板代码),定义基本属性地板、墙、天花板
@Getter @Setter @ToString public class House { /*地板*/ private String floor; /*墙*/ private String wall; /*屋顶*/ private String top; }
-
MainApp主类进行测试
public static void main(String[] args) { House house=new House(); house.setFloor("地板"); house.setWall("墙"); house.setTop("房顶"); System.out.println(house.toString()); }
这里我们可以看出有些问题了,首先,房子的建筑逻辑都被放在了外面,联想到日常生活中买房的经历,我们把测试类当作看房的过程,难道买房的人需要自己建房子吗?肯定不是,一定需要专门的建筑工人和管理阶级来维护。
-
为改造上面的代码,先创建HouseBuilder建造者接口,定义基本属性地板、墙、天花板的建造方法
public interface HouseBuilder { void makeFloor(); void makeWall(); void makeTop(); House getHouse(); }
-
再创建别墅、公寓建造者类,实现HouseBuilder接口,重写建造方法
//别墅HouseBuilder public class VillaHouseBuilder implements HouseBuilder { private static final String houseType="别墅--"; private House house=new House(); @Override public void makeFloor() { house.setFloor(houseType+"地板"); } @Override public void makeWall() { house.setWall(houseType+"墙"); } @Override public void makeTop() { house.setTop(houseType+"天花板"); } @Override public House getHouse() { return house; } } //公寓HouseBuilder代码同上
-
最后一步,也是非常核心的一步,因为买房的人一般都是跟销售管理人员打交道,而不是直接和建造团队沟通,因此,我们还需要一个核心领导者(HouseDirector)
public class HouseDirector { public House makeHouse(HouseBuilder houseBuilder){ houseBuilder.makeFloor(); houseBuilder.makeWall(); houseBuilder.makeTop(); return houseBuilder.getHouse(); } }
它负责将复合对象的创建过程抽象化,通过在它内部调用makeHouse方法,根据传入的房子建筑器,建造出需要的房子
-
最终交付测试,买家看房
public static void main(String[] args) { //创建销售领导者 HouseDirector houseDirector=new HouseDirector(); //建造出别墅 House villa = houseDirector.makeHouse(new VillaHouseBuilder()); System.out.println(house.toString()); //建造出公寓 House apartment = houseDirector.makeHouse(new ApartmentHouseBuilder()); System.out.println(apartment.toString()); }
三、总结
建造者模式通常包括以下角色:
- Director:调用具体建造者来创建对应的复杂对象,不涉及产品的具体信息,只保证对象各个部分被完整的创建或者按照某个顺序被创建
- Buidler:抽象建造接口,定义产品的每个组件的建造规范
- ConcreteBuilder:具体建造类,针对不同需求有不同的建造者,里面包含复杂对象的创建流程
- Product:最终需要的产品对象,在我们这个例子当中,产品是房子
其优点有:
- 使用建造者模式可以使客户端不必知道产品内部组成的细节。
- 具体的建造者类之间是相互独立的,对系统的扩展非常有利。
- 由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其它的模块产生任何影响。