一、建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创造不同的表示。

特点:

  (1)、在某些属性没有赋值之前,复杂对象不能作为一个完整的产品使用。比如汽车包括方向盘、车门、发动机等各部件,缺少了这些部件就不能生产使用。

  (2)、对象的一些属性必须按照顺序赋值,比如汽车应有车架才能装车轮和其他部件。

建造者模式涉及到以下四个角色的概念:

  - 抽象建造者角色:提供一个接口,规范产品对象的建造,一般由子类实现。一般来说,产品的组成部分数与建造方法数相同,即有多少组成部分,就有多少个建造方法。

  - 具体建造者角色:该角色实现了抽象建造者抽象建造者接口,主要是实现所有声明的方法以及返回建造好的产品实例。

  - 导演者角色:负责调用具体建造者按照顺序建造产品。导演者只负责调度,真正执行的是具体建造者角色。

  - 产品角色:该角色是建造的复杂对象,提供基本方法。

具体实现

1、创建产品角色

 public class Production {

     private String part1;

     private String part2;

     public String getPart1() {
return part1;
} public void setPart1(String part1) {
this.part1 = part1;
} public String getPart2() {
return part2;
} public void setPart2(String part2) {
this.part2 = part2;
} @Override
public String toString() {
return "Production{" +
"part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
'}';
}
}

2、创建抽象建造者角色

 public interface IBuilder {

     //产品有多少个组件,就有多少个建造方法
void buildPart1(); void buildPart2(); //返回产品类 Production build(); }

3、创建具体建造者角色

 public class BuilderA implements IBuilder{

     private  Production production = new Production() ;

     @Override
public void buildPart1() {
System.out.println("兰博基尼建造第一部分");
this.production.setPart1("This is part1 of Lamborghini");
} @Override
public void buildPart2() {
System.out.println("兰博基尼建造第二部分");
this.production.setPart2("This is part2 of Lamborghini");
} @Override
public Production build() {
System.out.println("咔擦!兰博基尼已造好!");
return this.production;
}
}

4、创建导演者角色

 public class Director {

     private IBuilder builder;

     public Director(IBuilder builder){
this.builder = builder;
} /**
* 开始具体构造
*/
public Production construct(){
this.builder.buildPart1();
this.builder.buildPart2(); return this.builder.build();
}
}

5、客户端调用

 public class Client {
public static void main(String[] args) {
//建造一个产品A
IBuilder builder = new BuilderA();
Director director = new Director(builder);
System.out.println(director.construct());
}
}

运行结果

兰博基尼建造第一部分
兰博基尼建造第二部分
咔擦!兰博基尼已造好!
Production{part1='This is part1 of Lamborghini', part2='This is part2 of Lamborghini'}

优点

1)降低代码耦合度。在建造者模式中,客户端不需要知道产品内部是如何实现的,我们只需得到产品的对象。并且使用导演者和建造者分离组装过程和组件具体构造过程,具有灵活的扩展性。

2)优秀的扩展性。具体建造者相互独立,方便扩展,符合开闭原则。

缺点

1)一定的使用范围限制。建造者模式的产品的组件基本相同,如果产品的差异性较大,建造者模式就不适用了。

跟工厂方法模式对比:建造者模式和工厂模式同样是创建一个产品,工厂模式就是一个方法,而建造者模式有多个方法,并且建造者模式是有顺序的执行方法。就是说建造者模式强调的是顺序,而工厂模式没有顺序一说。

二、原型模式

通过复制一个已存在对象来生成一个新对象,被复制的对象称为原型;

 补充:

1、JAVA中Object的clone方法已经为什么提供了复制对象的实现,且该方法为本地方法,性能好,在需要大量复制对象的情况,使用clone创建对象比new效率高;

补充下深拷贝和浅拷贝,深拷贝是通过拷贝内存(包括引用的对象)实现对象的创建;浅拷贝不拷贝引用的对象,但拷贝了引用的值,如果类的成员属性中都是基本类型,不含对象,也是可以达到深拷贝的效果;深拷贝可以通过将对象序列化成字节流以及反序列化实现,浅拷贝直接调用clone即可;

2、使用原型模式创建对象是没有调用类的构造方法的;

java已经很好的支持原型模式了,使用很简便,如下类,实现了Cloneable接口,即成了一个原型;

(参考另一篇博客:java的clone方法

 package com.pichen.dp.creationalpattern.prototype;

 public class Cell implements Cloneable{
private int cellId;
public int getCellId() {
return cellId;
}
public void setCellId(int cellId) {
this.cellId = cellId;
}
public Cell(int id) {
this.cellId = id;
}
@Override
public Object clone() throws CloneNotSupportedException
{
System.out.println("clone a cell obj.");
return (Cell) super.clone();
}
}

使用原型,复制10个拷贝:

 package com.pichen.dp.creationalpattern.prototype;

 public class Main {

     public static void main(String[] args) throws CloneNotSupportedException {
Cell prototypeCell = new Cell(888);
for(int i = 0; i < 10; i++){
Cell copyCell = (Cell) prototypeCell.clone();
System.out.println(copyCell.hashCode() + ":" + copyCell.getCellId());
}
}
}
05-21 07:02