5.设计模式----prototype原型模式

      原型模式:做到是原型,那肯定是自己本身才是原型,原型模式属于对象的创建模式

   关于原型模式的实现方式分2种:

         (1)简单形式、(2)登记形式,这两种表现形式仅仅是原型模式的不同实现。

 1 package inter.method;
 2 /**
 3  * 提供一个具有复制本身的接口
 4  * @author zengrong
 5  *
 6  */
 7 public interface Prototype {
 8 
 9       public Object clone();
10 }

 

 1 package impl.method;
 2 
 3 import inter.method.Prototype;
 4 
 5 public class ConcretePrototype1 implements Prototype {
 6     /**
 7      * 接口类对象使用了object,所有在复写时候,类型就随便都是可以的
 8      */
 9       public Prototype clone(){
10             //最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
11             Prototype prototype = new ConcretePrototype1();
12             return prototype;
13         }
14 }
 1 package impl.method;
 2 
 3 import inter.method.Prototype;
 4 
 5 /**
 6  * 客户端
 7  * @author zengrong
 8  *
 9  */
10 public class Client {
11 
12     /**
13      * 需要创建的原型
14      */
15     
16     private Prototype prototype;
17     
18     public Client( Prototype prototype){
19         this.prototype=prototype;
20     }
21     /**
22      * 创建原型
23      */
24     public void create () {
25         Prototype cloneprototype = (Prototype) prototype.clone();
26     }
27 }

第二种原型模式:登记模式。就是价将原先进行实例的方式是客户端和原型直接联系,这样耦合性高,解决办法就是设置一个管理器进行来管理生成这些原型,

 

 1 package inter.pro.two;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 /**
 7  * 原型管理器
 8  * @author zengrong
 9  *,作为对所有原型对象的登记,
10  *这个角色提供必要的方法,
11  *供外界增加新的原型对象和取得已经登记过的原型对象。
12  */
13 public class PromManger {
14         /**
15          * 用来记录原型
16          */
17     private static Map<String,PrototypeTwo> map = new HashMap<String,PrototypeTwo>();
18         
19     private PromManger(){}//私有化构造
20     
21     /**
22      * 设置一个方法来进行向原型集合中添加
23      */
24     public synchronized static void setPrototypes(String prototypeId,PrototypeTwo prototypeTwo) {
25         map.put(prototypeId, prototypeTwo);
26         
27     }
28      /**
29      * 从原型管理器里面删除某个原型注册
30      * @param prototypeId 原型编号
31      */
32     public synchronized static void removePrototype(String prototypeId){
33         map.remove(prototypeId);
34     }
35     
36     /**
37      * 获取原型
38      */
39     public synchronized static  PrototypeTwo getPrototypeTwo( String prototypeId) {
40         PrototypeTwo prototypeTwo = map.get(prototypeId);
41         if(prototypeTwo==null){
42             System.out.println("该原型还没有进行登记注册------无法获取---");
43         }
44         return prototypeTwo;
45     }
46     
47     
48     
49 }
 1 package inter.pro.two;
 2 
 3 public class PrototypeCol implements PrototypeTwo {
 4         private String name;
 5         public PrototypeTwo clone(){
 6             PrototypeCol prototype = new PrototypeCol();
 7             prototype.setName(this.name);
 8             return prototype;
 9         }
10         public String toString(){
11             return "Now in Prototype1 , name = " + this.name;
12         }
13         @Override
14         public String getName() {
15             return name;
16         }
17 
18         @Override
19         public void setName(String name) {
20             this.name = name;
21         }
22     }
 1 package inter.pro.two;
 2 /**
 3  * 
 4  * @author zengrong
 5  *
 6  */
 7 public interface PrototypeTwo {
 8         /**
 9          * 具体的原型
10          * @return
11          */
12         public PrototypeTwo clone();
13         public String getName();
14         public void setName(String name);
15     
16     
17 }

简单原型和登记原型对比:

      在原型数量很少的情况下,采用第一种方式,客户端呢保存原型,

      但是在数量不确定的情况下,采用第二中方式,在复制一个原型对象之前,客户端可以查看管理员对象是否已经有一个满足要求的原型对象。如果有,可以直接从管理员类取得这个对象引用;如果没有,客户端就需要自行复制此原型对象。

 

在Java中有个方法和这个其实是一样的,Java中得克隆方法;

  Java的所有类都是从java.lang.Object类继承而来的,而Object类提供protected Object clone()方法对对象进行复制,子类当然也可以把这个方法置换掉,提供满足自己需要的复制方法。对象的复制有一个基本问题,就是对象通常都有对其他的对象的引用。当使用Object类的clone()方法来复制一个对象时,此对象对其他对象的引用也同时会被复制一份

  Java语言提供的Cloneable接口只起一个作用,就是在运行时期通知Java虚拟机可以安全地在这个类上使用clone()方法。通过调用这个clone()方法可以得到一个对象的复制。由于Object类本身并不实现Cloneable接口,因此如果所考虑的类没有实现Cloneable接口时,调用clone()方法会抛出CloneNotSupportedException异常。

 

克隆满足的条件

clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的。一般而言,clone()方法满足以下的描述:

  (1)对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。

  (2)对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型一样。

  (3)如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。

  在JAVA语言的API中,凡是提供了clone()方法的类,都满足上面的这些条件。JAVA语言的设计师在设计自己的clone()方法时,也应当遵守着三个条件。一般来说,上面的三个条件中的前两个是必需的,而第三个是可选的。

 

 

 

 

在这里其实涉及到一个值传递和引用传递!

 

 

 

 

 

 

  

posted @ 2017-04-06 23:20  指针怒草内存栈  阅读(236)  评论(0编辑  收藏  举报