创建型设计模式---原型模式和建造者模式

一、原型模式

       原型模式指原型实例指定创建对象的种类,通过拷贝这些原型对象创建新的对象。原型模式不需要知道任何创建的细节,不调用构造函数,而且原型模式的性能比直接new一个对象性能高



1、基于浅拷贝的原型模式

       所谓浅拷贝即拷贝出一个对象,但是拷贝出来的对象属性指向的还是原来的内存空间。浅拷贝直接使用默认生成的clone方法即可。

       能力表类:

	public class CapacityTable implements Cloneable {
	    private int attackValue;
	    private int defenseValue;
	
	    public int getAttackValue() {
	        return attackValue;
	    }
	
	    public void setAttackValue(int attackValue) {
	        this.attackValue = attackValue;
	    }
	
	    public int getDefenseValue() {
	        return defenseValue;
	    }
	
	    public void setDefenseValue(int defenseValue) {
	        this.defenseValue = defenseValue;
	    }
	
	    public CapacityTable(int attackValue, int defenseValue) {
	        this.attackValue = attackValue;
	        this.defenseValue = defenseValue;
	    }
	
	    @Override
	    protected Object clone() throws CloneNotSupportedException {
	        return super.clone();
	    }
	}

       战神类:

	public class GodOfWar implements Cloneable {
	    private CapacityTable capacity;
	    private int age;
	
	    public CapacityTable getCapacity() {
	        return capacity;
	    }
	
	    public void setCapacity(CapacityTable capacity) {
	        this.capacity = capacity;
	    }
	
	    public int getAge() {
	        return age;
	    }
	
	    public void setAge(int age) {
	        this.age = age;
	    }
	
	    public GodOfWar(CapacityTable capacity, int age) {
	        this.capacity = capacity;
	        this.age = age;
	    }
	
	    @Override
	    protected Object clone() throws CloneNotSupportedException {
	        return super.clone();
	    }
	}

       测试代码:

	GodOfWar hero = new GodOfWar(new CapacityTable(20, 20), 23);
    GodOfWar copy = (GodOfWar) hero.clone();
    System.out.println(hero);
    System.out.println(copy);
    System.out.println(hero.getCapacity());
    System.out.println(copy.getCapacity());
    System.out.println(copy.getCapacity() == hero.getCapacity());

       运行结果(结果表明两个对象中的capacity属性指向的是一块内存空间):

Alt



2、基于逐层实现clone方法深拷贝的原型模式

       所谓深拷贝就是拷贝出一个对象,而且对象里面的所有属性指向的也是不同的内存空间
       深拷贝需要手动一层层的实现clone方法。

       修改战神类代码的clone方法如下:

	@Override
    protected Object clone() throws CloneNotSupportedException {
        GodOfWar godOfWar = (GodOfWar) super.clone();
        if (godOfWar != null) {
            godOfWar.capacity = (CapacityTable) capacity.clone();
        }
        return godOfWar;
    }

       还是使用上面的测试代码,结果如下图(可见已经达到了深拷贝的目的):

Alt



3、基于序列化和反序列化实现深拷贝的原型模式

       将原来的能力表类实现Serializable接口,并改写战神类如下:

	public class GodOfWar implements Cloneable, Serializable {
	    private CapacityTable capacity;
	    private int age;
	
	    public CapacityTable getCapacity() {
	        return capacity;
	    }
	
	    public void setCapacity(CapacityTable capacity) {
	        this.capacity = capacity;
	    }
	
	    public int getAge() {
	        return age;
	    }
	
	    public void setAge(int age) {
	        this.age = age;
	    }
	
	    public GodOfWar(CapacityTable capacity, int age) {
	        this.capacity = capacity;
	        this.age = age;
	    }
	
	    @Override
	    protected Object clone() throws CloneNotSupportedException {
	        GodOfWar godOfWar = (GodOfWar) super.clone();
	        if (godOfWar != null) {
	            godOfWar.capacity = (CapacityTable) capacity.clone();
	        }
	        return godOfWar;
	    }
	
	    public Object deepClone() throws IOException, ClassNotFoundException {
	        //序列化
	        ByteArrayOutputStream bos = new ByteArrayOutputStream();
	        ObjectOutputStream oos = new ObjectOutputStream(bos);
	
	        oos.writeObject(this);
	
	        //反序列化
	        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
	        ObjectInputStream ois = new ObjectInputStream(bis);
	
	        return ois.readObject();
	    }
	}

       测试代码:

	GodOfWar hero = new GodOfWar(new CapacityTable(20, 20), 23);
    GodOfWar copy = (GodOfWar) hero.deepClone();
    System.out.println(hero);
    System.out.println(copy);
    System.out.println(hero.getCapacity());
    System.out.println(copy.getCapacity());
    System.out.println(copy.getCapacity() == hero.getCapacity());

       测试结果(可见已经达到了深拷贝的目的):
Alt




二、建造者模式

       建造者模式即使用多个简单的对象一步一步构建成一个复杂的对象,可以将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。



1、普通的建造者模式

       要建造的类:

	public class Product {
	    private String buildA;
	    private String buildB;
	    private String buildC;
	    private String buildD;
	
	    public String getBuildA() {
	        return buildA;
	    }
	
	    public void setBuildA(String buildA) {
	        this.buildA = buildA;
	    }
	
	    public String getBuildB() {
	        return buildB;
	    }
	
	    public void setBuildB(String buildB) {
	        this.buildB = buildB;
	    }
	
	    public String getBuildC() {
	        return buildC;
	    }
	
	    public void setBuildC(String buildC) {
	        this.buildC = buildC;
	    }
	
	    public String getBuildD() {
	        return buildD;
	    }
	
	    public void setBuildD(String buildD) {
	        this.buildD = buildD;
	    }
	
	    @Override
	    public String toString() {
	        return "Product{" +
	                "buildA='" + buildA + '\'' +
	                ", buildB='" + buildB + '\'' +
	                ", buildC='" + buildC + '\'' +
	                ", buildD='" + buildD + '\'' + super.toString() +
	                '}';
	    }
	}

       抽象的建造者类:

	public abstract class Builder {
	    abstract void buildA();     //地基
	
	    abstract void buildB();     //钢筋工程
	
	    abstract void buildC();     //铺电线
	
	    abstract void buildD();     //粉刷
	
	    abstract Product getProduct();      //完工-获取产品
	}

       具体的建造者类:

	public class ConcreteBuilder extends Builder {
	    private Product product;
	
	    public ConcreteBuilder() {
	        product = new Product();
	    }
	
	    @Override
	    void buildA() {
	        product.setBuildA("地基");
	    }
	
	    @Override
	    void buildB() {
	        product.setBuildB("钢筋工程");
	    }
	
	    @Override
	    void buildC() {
	        product.setBuildC("铺电线");
	    }
	
	    @Override
	    void buildD() {
	        product.setBuildD("粉刷");
	    }
	
	    @Override
	    Product getProduct() {
	        return product;
	    }
	}

       指导者类:

	public class Director {
	    public Product create(Builder builder) {
	        builder.buildA();
	        builder.buildB();
	        builder.buildC();
	        builder.buildD();
	        return builder.getProduct();
	    }
	}

       测试代码:

	Director director = new Director();
    Product product = director.create(new ConcreteBuilder());
    System.out.println(product);

       测试结果:

Alt



2、链式调用的建造者模式

       使用公共的静态内部类完成链式调用的建造

       要建造的类:

	public class Product {
	    private String buildA;
	    private String buildB;
	    private String buildC;
	    private String buildD;
	
	    public Product(ProductBuilder builder) {
	        this.buildA = builder.buildA;
	        this.buildB = builder.buildB;
	        this.buildC = builder.buildC;
	        this.buildD = builder.buildD;
	    }
	
	
	    public static class ProductBuilder {
	        private String buildA;
	        private String buildB;
	        private String buildC;
	        private String buildD;
	
	        public ProductBuilder setBuildA(String buildA) {
	            this.buildA = buildA;
	            return this;
	        }
	
	        public ProductBuilder setBuildB(String buildB) {
	            this.buildB = buildB;
	            return this;
	        }
	
	        public ProductBuilder setBuildC(String buildC) {
	            this.buildC = buildC;
	            return this;
	        }
	
	        public ProductBuilder setBuildD(String buildD) {
	            this.buildD = buildD;
	            return this;
	        }
	
	        public Product build() {
	            return new Product(this);
	        }
	
	    }
	
	    @Override
	    public String toString() {
	        return "Product{" +
	                "buildA='" + buildA + '\'' +
	                ", buildB='" + buildB + '\'' +
	                ", buildC='" + buildC + '\'' +
	                ", buildD='" + buildD + '\'' + super.toString() +
	                '}';
	    }
	}

       测试代码:

	Product product = new Product.ProductBuilder()
            .setBuildA("地基")
            .setBuildB("钢筋工程")
            .setBuildC("铺电线")
            .setBuildD("粉刷")
            .build();
    System.out.println(product);

       测试结果:

Alt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值