设计模式——创建者模式
将一个“复杂对象的构建算法”与它的“部件及组装方式”分离,使得构件算法和组装方式可以独立应对变化;复用同样的构建算法可以创建不同的表示,不同的构建过程可以复用相同的部件组装方式。
客户端不需知道创建的具体细节,只需对指挥者下命令,这就解耦了客户端和创建者,这个指挥者感觉有点像一个工厂,但是工厂模式解决的是对象的构造,而创建者模式解决的是对象创建过程中的排列组合。
实现要点
在建造者模式中,指挥者是直接与客户端打交道的,指挥者将客户端创建产品的请求划分为对各个部件的建造请求,再将这些请求委派到具体建造者角色,具体建造者角色是完成具体产品的构建工作的,却不为客户所知道。建造者模式主要用于“分步骤来构建一个复杂的对象”,其中“分步骤”是一个固定的组合过程,而复杂对象的各个部分是经常变化的(也就是说电脑的内部组件是经常变化的,这里指的的变化如硬盘的大小变了,CPU由单核变双核等)。
产品不需要抽象类,由于建造模式的创建出来的最终产品可能差异很大,所以不大可能提炼出一个抽象产品类。
在前面文章中介绍的抽象工厂模式解决了“系列产品”的需求变化,而建造者模式解决的是 “产品部分” 的需要变化。
由于建造者隐藏了具体产品的组装过程,所以要改变一个产品的内部表示,只需要再实现一个具体的建造者就可以了,从而能很好地应对产品组成组件的需求变化。
实现
之前说的女娲造人,通过不同的工厂都能造出来。现在把造人过程细化,根据地区造人,并且先造身体,再造头发,通过创建者模式来实现。类图如下:
实现代码如下:
身体接口:
package com.lidaming.design04.builder; public interface IBody { String color(); String height(); }
身体的实现:
package com.lidaming.design04.builder; public class BlackHighMan implements IBody { public String color() { return "black"; } public String height() { return "high"; } }
package com.lidaming.design04.builder; public class YellowHeightMan implements IBody { public String color() { return "yellow"; } public String height() { return "long"; } }
头发接口:
package com.lidaming.design04.builder; public interface IHair { String color(); String length(); }
头发的实现:
package com.lidaming.design04.builder; public class LongWhiteHair implements IHair { public String color() { // TODO Auto-generated method stub return "white"; } public String length() { // TODO Auto-generated method stub return "long"; } }
package com.lidaming.design04.builder; public class ShortBlackHair implements IHair { public String color() { // TODO Auto-generated method stub return "black"; } public String length() { // TODO Auto-generated method stub return "short"; } }
人类的实现:
package com.lidaming.design04.builder; public class Human { private IBody body; public IBody getBody() { return body; } public void setBody(IBody body) { this.body = body; } private IHair hair; public IHair getHair() { return hair; } public void setHair(IHair hair) { this.hair = hair; } public void show() { System.out.print("this man "); if(body!=null) System.out.print(" is "+body.height()+" "+body.color()+" and "); if(hair!=null) System.out.print("has "+hair.length()+" "+hair.color()+" hair"); System.out.println(); } }
创建接口的定义:
package com.lidaming.design04.builder; public interface IBuilder { void buildHair(); void buildBody(); Human getHuman(); }
创建类的实现:
package com.lidaming.design04.builder; public class ConcreteBuilder implements IBuilder { Human human = new Human(); public void buildHair() { if (!human.getBody().equals(null)) { human.setHair(new LongWhiteHair()); } else { System.out.println(" this man has no body now!"); } } public void buildBody() { human.setBody(new BlackHighMan()); } public Human getHuman() { return human; } }
package com.lidaming.design04.builder; public class AsiaBuilder implements IBuilder { Human human = new Human(); public void buildHair() { if (human.getBody().equals(null)) { System.out.println("this man has no body now"); return; } human.setHair(new ShortBlackHair()); } public void buildBody() { human.setBody(new YellowHeightMan()); } public Human getHuman() { // TODO Auto-generated method stub return human; } }
指导类的实现:
package com.lidaming.design04.builder; public class Director { public void construct(IBuilder builder) { builder.buildBody(); builder.buildHair(); } }
场景类的实现:
package com.lidaming.design04.builder; public class Client { public static void main(String[] args) { Director director = new Director(); IBuilder builder = new ConcreteBuilder(); director.construct(builder); Human human = builder.getHuman(); human.show(); builder = new AsiaBuilder(); director.construct(builder); human = builder.getHuman(); human.show(); } }
总结
建造者模式(Builder Pattern),将一个复杂对象的构建与它的表示分离,使的同样的构建过程可以创建不同的表示。建造者模式的本质是使组装过程(用指挥者类进行封装,从而达到解耦的目的)和创建具体产品解耦,使我们不用去关心每个组件是如何组装的。