建造者设计模式
生活中的场景
当电脑第一次安装软件的时候,开始总是引导页面和欢迎页面,中间就是使用的过程了,当卸载软件的时候,需要好几次的确认,
package com.cloud.Test; public class Test3 { public static void main(String[] args) { BuilderSoft soft = new WelBuilder(); Direct direct = new Direct(soft); direct.construct(); } } /** * @ClassName: UseSoft * @Description: 定义一个抽象的软件使用类 * @author午_夜 * @date 2016-8-7 下午10:57:17 */ abstract class UseSoft{ /*杀毒操作*/ private String killvirus; /*清理垃圾*/ private String clearwaste; /*电脑监控*/ private String detection; public void user(){ System.out.println("杀毒操作:" + killvirus); System.out.println("清理垃圾:" + clearwaste); System.out.println("电脑监控:" + detection); } public String getKillvirus() { return killvirus; } public void setKillvirus(String killvirus) { this.killvirus = killvirus; } public String getClearwaste() { return clearwaste; } public void setClearwaste(String clearwaste) { this.clearwaste = clearwaste; } public String getDetection() { return detection; } public void setDetection(String detection) { this.detection = detection; } } /** * @ClassName: WelcomeUseSoft * @Description: 具体的产品类:软件第一次使用都会有引导欢迎页面 * @author午_夜 * @date 2016-8-7 下午11:03:29 */ class WelcomeUseSoft extends UseSoft{ public void welmessage(){ System.out.println("欢迎使用xxx杀毒软件"); } } /** * @ClassName: ByeUseSoft * @Description: 软件卸载的欢送页面 * @author午_夜 * @date 2016-8-7 下午11:05:07 */ class ByeUseSoft extends UseSoft{ public void byemessage(){ System.out.println("真的卸载吗?"); System.out.println("真的卸载吗?"); System.out.println("真的卸载吗?"); } } /** * @ClassName: BuilderSoft * @Description: 抽象的建造者类 * @author午_夜 * @date 2016-8-7 下午11:07:52 */ abstract class BuilderSoft{ protected UseSoft useSoft; //欢迎标题零件的建造方法 public abstract void buildSubject(); //欢迎内容零件的建造方法 public abstract void buildBody(); //垃圾清理零件的建造方法 public void clearwaste(String clearwaste){ useSoft.setClearwaste(clearwaste); } //杀毒的建造方法 public void killvirus(String killvirus){ useSoft.setKillvirus(killvirus); } //电脑监控零件的建造方法 public void detection(String detection){ useSoft.setDetection(detection); } //使用软件 public void useSoft(){ useSoft.user(); } } /** * @ClassName: WelBuilder * @Description: 具体建造者类 * @author午_夜 * @date 2016-8-7 下午11:18:06 */ class WelBuilder extends BuilderSoft{ public WelBuilder(){ useSoft = new WelcomeUseSoft(); } @Override public void buildSubject() { System.out.println("欢迎:"); } @Override public void buildBody() { System.out.println("第一次使用xxx杀毒软件"); } } /** * @ClassName: ByeBuilder * @Description: 具体的建造者类 * @author午_夜 * @date 2016-8-7 下午11:19:16 */ class ByeBuilder extends BuilderSoft{ public ByeBuilder(){ useSoft = new ByeUseSoft(); } @Override public void buildSubject() { System.out.println("再见:"); } @Override public void buildBody() { System.out.println("我还会再回来的..."); } } /** * @ClassName: Direct * @Description: 导演类 * @author午_夜 * @date 2016-8-7 下午11:24:16 */ class Direct{ BuilderSoft builder; public Direct(BuilderSoft builder){ this.builder = builder; } public void construct(){ this.builder.buildSubject(); this.builder.clearwaste("1.垃圾清理"); this.builder.detection("2.电脑检测"); this.builder.killvirus("3.电脑杀毒"); this.builder.buildBody(); } } |
建造者模式
定义:
建造模式是对象的创建模式。建造模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
也就是使用一个中介对象封装一系列的对象交互,使其各个对象不需要显示的相互调用,而且可以单独的改变对象之间的交互。
图解:
图解分析:
抽象建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。模式中直接创建产品对象的是具体建造者 (ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法(buildPart1和 buildPart2),另一种是返还结构方法(retrieveResult)。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少零件,就有多少相应的建造方法。
具体建造者(ConcreteBuilder)角色:完成的任务包括:1.实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作。2.在建造过程完成后,提供产品的实例。
导演者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。
产品(Product)角色:产品便是建造中的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的。
公共代码抽取
package com.cloud.Test;
/** * @ClassName: Test2 * @Description: 客户端类 * @author午_夜 * @date 2016-8-5 下午5:28:07 */ public class Test2 { public static void main(String[] args) { Builder builder = new ConcreateBuilder(); Director director = new Director(builder); director.constrct(); Product product = builder.builderProduct(); System.out.println(product.getAct1()); System.out.println(product.getAct2()); } } /** * @ClassName: Product * @Description: 产品类 * @author午_夜 * @date 2016-8-5 下午4:59:03 */ class Product{ /*定义一些产品的操作*/ private String act1; private String act2; public String getAct1() { return act1; } public void setAct1(String act1) { this.act1 = act1; } public String getAct2() { return act2; } public void setAct2(String act2) { this.act2 = act2; } } /** * @ClassName: Builder * @Description: 抽象建造者类 * @author午_夜 * @date 2016-8-5 下午5:02:30 */ abstract class Builder{ public abstract void builderact1(); public abstract void builderact2(); public abstract Product builderProduct(); } /** * @ClassName: ConcreateBuilder * @Description: 具体建造者类 * @author午_夜 * @date 2016-8-5 下午5:06:01 */ class ConcreateBuilder extends Builder{ private Product product = new Product(); @Override public void builderact1() { product.setAct1("操作一:"); } @Override public void builderact2() { product.setAct2("操作二:"); } @Override public Product builderProduct() { return product; } } /** * @ClassName: Director * @Description: 导演者类 * @author午_夜 * @date 2016-8-5 下午5:10:23 */ class Director{ /*使用建造者抽象类*/ private Builder builder; public Director(Builder builder){ this.builder = builder; } /*负责调用各个建造方法*/ public void constrct(){ builder.builderact1(); builder.builderact2(); } } |
实际应用
优缺点
优点:减少类之间的相互依赖,降低耦合度。
缺点:ConcreateBuilder变得臃肿庞大,逻辑复杂。
使用场景
1. 在JavaWeb中的MVC模式的控制层,分隔前后台交互,在中间起到枢纽的作用。
2. 需要生成的产品对象有复杂的内部结构,每一个内部成分本身可以是对象,也可以仅仅是一个对象(即产品对象)的一个组成部分。
3. 需要生成的产品对象的属性相互依赖。建造模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造模式是一个很好的设计思想。
4. 在对象创建过程中会使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到。