java23种设计模式(二)-- 建造者模式和原型模式

一、建造者模式

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

特点:

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

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

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

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

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

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

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

具体实现

1、创建产品角色

 1 public class Production {
 2 
 3     private String part1;
 4 
 5     private String part2;
 6 
 7     public String getPart1() {
 8         return part1;
 9     }
10 
11     public void setPart1(String part1) {
12         this.part1 = part1;
13     }
14 
15     public String getPart2() {
16         return part2;
17     }
18 
19     public void setPart2(String part2) {
20         this.part2 = part2;
21     }
22 
23     @Override
24     public String toString() {
25         return "Production{" +
26                 "part1='" + part1 + '\'' +
27                 ", part2='" + part2 + '\'' +
28                 '}';
29     }
30 }
View Code

2、创建抽象建造者角色

 1 public interface IBuilder {
 2 
 3     //产品有多少个组件,就有多少个建造方法
 4      void buildPart1();
 5 
 6      void buildPart2();
 7 
 8      //返回产品类
 9 
10     Production build();
11 
12 }
View Code

3、创建具体建造者角色

 1 public class BuilderA implements IBuilder{
 2 
 3     private  Production production = new Production() ;
 4 
 5     @Override
 6     public void buildPart1() {
 7         System.out.println("兰博基尼建造第一部分");
 8         this.production.setPart1("This is part1 of Lamborghini");
 9     }
10 
11     @Override
12     public void buildPart2() {
13         System.out.println("兰博基尼建造第二部分");
14         this.production.setPart2("This is part2 of Lamborghini");
15     }
16 
17     @Override
18     public Production build() {
19         System.out.println("咔擦!兰博基尼已造好!");
20         return this.production;
21     }
22 }
View Code

4、创建导演者角色

 1 public class Director {
 2 
 3     private IBuilder builder;
 4 
 5     public Director(IBuilder builder){
 6         this.builder = builder;
 7     }
 8 
 9     /**
10      * 开始具体构造
11      */
12     public Production construct(){
13         this.builder.buildPart1();
14         this.builder.buildPart2();
15 
16         return this.builder.build();
17     }
18 }
View Code

5、客户端调用

1 public class Client {
2     public static void main(String[] args) {
3         //建造一个产品A
4         IBuilder builder = new BuilderA();
5         Director director = new Director(builder);
6         System.out.println(director.construct());
7     }
8 }
View Code

运行结果

兰博基尼建造第一部分
兰博基尼建造第二部分
咔擦!兰博基尼已造好!
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方法

 1 package com.pichen.dp.creationalpattern.prototype;
 2 
 3 public class Cell implements Cloneable{
 4     private int cellId;
 5     public int getCellId() {
 6         return cellId;
 7     }
 8     public void setCellId(int cellId) {
 9         this.cellId = cellId;
10     }
11     public Cell(int id) {
12         this.cellId = id;
13     }
14     @Override
15     public Object clone() throws CloneNotSupportedException
16     {
17         System.out.println("clone a cell obj.");
18         return (Cell) super.clone();
19     }
20 }
View Code

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

 1 package com.pichen.dp.creationalpattern.prototype;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) throws CloneNotSupportedException {
 6         Cell prototypeCell = new Cell(888);
 7         for(int i = 0; i < 10; i++){
 8             Cell copyCell = (Cell) prototypeCell.clone();
 9             System.out.println(copyCell.hashCode() + ":" + copyCell.getCellId());
10         }
11     }
12 }
View Code

 

posted @ 2019-06-10 17:00  炫舞风中  阅读(188)  评论(0编辑  收藏  举报