zoukankan      html  css  js  c++  java
  • 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()方法时,也应当遵守着三个条件。一般来说,上面的三个条件中的前两个是必需的,而第三个是可选的。

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

     

      

  • 相关阅读:
    在阿里云“专有网络”网络类型中配置vsftpd
    Ubuntu 16.04下开启Mysql 3306端口远程访问
    .net core 2.0 报错:error NU1102: Unable to find package ...
    .NET Core Runtime ARM32 builds now available
    .NET Core on Raspberry Pi
    .NET Core 跨平台发布(dotnet publish)
    使用vscode开发调试.net core应用程序并部署到Linux跨平台
    docker容器镜像删除
    使用阿里docker镜像加速器加速
    树莓派3b基于UbuntuMate下载中文输入法
  • 原文地址:https://www.cnblogs.com/java-synchronized/p/6675994.html
Copyright © 2011-2022 走看看