java设计模式-建造者模式
燕雀安知毛驴之志 人气:0建造者模式
一,什么是建造者模式
定义:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是23种设计模式中创建型模式中的一种,我们知道创建模式有五种,分别是单例模式、工厂方法模式、抽象工厂模式、原型模式及建造者模式,这些模式无一例外都是用于创建某个类的对象实例。
什么场景可以用建造者模式:当一个类的构造过多时并且个别参数可选填,这时可以考虑使用用建造者模式。
目的:是为了分离对象的属性与创建过程。
二,代码实现
实现建造者模式有两种方式:传统方式实现、静态内部类方式
废话不多说了直接上代码吧,代码更直观,下面一步一步来定义一个建造者模式。
下面例子以创建一个人为例,默认普通人,人有身体、耳朵、眼睛、牙齿等待。
1,Build 传统方式实现:
下面案例中我把构建得过程交给客户端不在单独实现,
第一步,首先创建我们的目标对象,
package pattern.build; /** * 产品 * @author ningbeibei */ public class Product { private String body="普通身体"; private String ear = "普通耳朵"; private String eye = "普通眼睛"; private String mouth = "普通牙齿"; public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getEar() { return ear; } public void setEar(String ear) { this.ear = ear; } public String getEye() { return eye; } public void setEye(String eye) { this.eye = eye; } public String getMouth() { return mouth; } public void setMouth(String mouth) { this.mouth = mouth; } }
第二步,定义建造者抽象类
package pattern.build; /** * 建造者抽象类 * @author ningbeibei */ public abstract class AbstractBuilder { abstract AbstractBuilder body(String msg);//身体 abstract AbstractBuilder mouth(String msg);//嘴巴 abstract AbstractBuilder ear(String msg);//耳朵 abstract AbstractBuilder eye(String msg);//眼睛 abstract Product getProduct();//获取产品 }
第三步,建造者类具体实现继承自 AbstractBuilder 抽象类并实现抽象方法 ,注意:具体建造者类中构造函数用来创建目标对象,
package pattern.build; /** * 具体建造者 * @author ningbeibei */ public class Build extends AbstractBuilder{ //声明产品属性 private Product product; //具体建造者构造函数用来创建产品对象 public Build() { product = new Product(); } @Override AbstractBuilder body(String msg) { product.setBody(msg); return this; } @Override AbstractBuilder mouth(String msg) { product.setMouth(msg); return this; } @Override AbstractBuilder ear(String msg) { product.setEar(msg); return this; } @Override AbstractBuilder eye(String msg) { product.setEye(msg); return this; } @Override Product getProduct() { return product; } }
第四步,测试类,我这没有写指挥者类,这个指挥者我交给客户端来做,建造者模式一般在构造复杂对象时可以考虑使用,根据不同得场景使用不同得设计模,但是在真正使用时基本上不会单独使用一种设计模,大多数都是混合使用,这就需要阅读代码者需要对设计模式足够了解和掌握。
package pattern.build; /** * 建造者模式测试类 * @author ningbeibei */ public class Test { public static void main(String[] args) { //创建构建对象 Build build1 = new Build(); //这里可以用方法链来组建对象 Product p = build1.body("金身").ear("顺风耳").getProduct(); System.out.println(p.getBody()+" "+p.getEar()+" "+p.getEye()+" "+p.getMouth()); } }
2,静态内部类方式实现:
a.首先创建一个 StaticBuild 类并定义属性封装get方法,我代码中定义属性用 final 修饰的,所以不需要set方法,把初始化属性放到静态内部类中;
b.在 StaticBuild 类中创建静态内部类 Builder (静态内部类)类;
c.创建 StaticBuild 类构造方法并用 private 修饰,参数为 Builder (静态内部类)类型;
d.在 Builder 中定义属性,可以把 StaticBuild 类属性复制到 Builder 类中(静态内部类属性去除 final 修饰符);
e.在 Builder 中创建设置函数,对 StaticBuild 中那些参数进行赋值,返回值为 Builder 类型的实例;
g.在 Builder 中创建一个 build() 方法,在其中构建 StaticBuild 的实例并返回;
请看完成代码:
package pattern.build; /** * 静态内部类实现建造者模式 * @author ningbeibei */ public class StaticBuild { private final String name; private final String age; private final String shengao; private final String toufa; //构造函数 private StaticBuild(Builder build){ this.name = build.name; this.age = build.age; this.shengao = build.shengao; this.toufa = build.toufa; } //静态内部类 public static class Builder{ private String name; private String age; private String shengao; private String toufa; //构造函数 public Builder(String name,String age) { this.name = name; this.age = age; } //设置属性值,返回Builder对象 public Builder setShengao(String shengao) { this.shengao = shengao; return this; } //设置属性值,返回Builder对象 public Builder setToufa(String toufa) { this.toufa = toufa; return this; } //构建StaticBuild对象并返回 public StaticBuild build(){ return new StaticBuild(this); } } public String getName() { return name; } public String getAge() { return age; } public String getShengao() { return shengao; } public String getToufa() { return toufa; } }
测试类
package pattern.build; /** * 建造者模式测试类 * @author ningbeibei */ public class Test { public static void main(String[] args) { //静态内部类式建造者模式 StaticBuild build = new StaticBuild.Builder("张三", "30").setShengao("178").setToufa("红").build(); System.out.println("姓名:"+build.getName()); System.out.println("年龄:"+build.getAge()); System.out.println("身高:"+build.getShengao()); System.out.println("头发:"+build.getToufa()); } }
三,写的不足之处请批评指正
加载全部内容