zoukankan      html  css  js  c++  java
  • 【设计模式】—— 原型模式Prototype

      前言:【模式总览】——————————by xingoo

      模式意图

      由于有些时候,需要在运行时指定对象时哪个类的实例,此时用工厂模式就有些力不从心了。通过原型模式就可以通过拷贝函数clone一个原有的对象,给现在的对象使用,从而创建更多的同类型的对象。

      模式结构

      【简单原型模式】用于原型的版本不多的时候

      【登记模式的原型模式】如果原型的实现很多种版本,那么通过一个登记管理类,可以方便的实现原型的管理。

      Prototype 原型接口,定义原型的结构。

      ConcretePrototype 原型的具体实现。

      Client 使用类,创建一个原型,创建一个引用,可以随意指定要引用的实现类。

      PrototypeManager 原型的管理器,里面含有一个Map,用来保存原型的实例对象。

      使用场景

      1 当需要在运行时指定对象的实现类时。

      2 当一个类的实例只能有集中状态的一种时。(这个没怎么理解)

      代码结构

      【简单原型模式

     1 package com.xingoo.test;
     2 
     3 interface Prototype{
     4     public Object clone();
     5 }
     6 class ConcretePrototype1 implements Prototype{
     7     public Object clone() {
     8         Prototype prototype = new ConcretePrototype1();
     9         return prototype;
    10     }
    11 }
    12 class ConcretePrototype2 implements Prototype{
    13     public Object clone(){
    14         Prototype prototype = new ConcretePrototype2();
    15         return prototype;
    16     }
    17 }
    18 public class Client{
    19     public static void main(String[] args){
    20         Prototype p1 = new ConcretePrototype1();
    21         System.out.println("p1 "+p1);
    22         
    23         Prototype p2 = new ConcretePrototype2();
    24         System.out.println("p2 "+p2);
    25         
    26         Prototype prototype = (Prototype)p1.clone();
    27         System.out.println("prototype "+prototype);
    28         prototype = (Prototype)p2.clone();
    29         System.out.println("prototype "+prototype);
    30     }
    31 }

      运行结果

    p1 com.xingoo.test.ConcretePrototype1@1fb8ee3
    p2 com.xingoo.test.ConcretePrototype2@14318bb
    prototype com.xingoo.test.ConcretePrototype1@ca0b6
    prototype com.xingoo.test.ConcretePrototype2@10b30a7

      【登记模式的原型模式

      1 package com.xingoo.test1;
      2 
      3 import java.util.HashMap;
      4 import java.util.Map;
      5 /**
      6  * 原型的接口
      7  * @author xingoo
      8  */
      9 interface Prototype{
     10     public Prototype clone();
     11 }
     12 /**
     13  * 具体的实现类1
     14  * @author xingoo
     15  *
     16  */
     17 class ConcretePrototype1 implements Prototype{
     18     public Prototype clone() {
     19         Prototype prototype = new ConcretePrototype1();
     20         return prototype;
     21     }
     22 }
     23 /**
     24  * 具体的实现类2
     25  * @author xingoo
     26  *
     27  */
     28 class ConcretePrototype2 implements Prototype{
     29     public Prototype clone(){
     30         Prototype prototype = new ConcretePrototype2();
     31         return prototype;
     32     }
     33 }
     34 /**
     35  * 原型的管理器
     36  * @author xingoo
     37  *
     38  */
     39 class PrototypeManager{
     40     /**
     41      * 用于保存原型的实例
     42      */
     43     private static Map<String,Prototype> map = new HashMap<String,Prototype>();
     44     /**
     45      * 静态方法创建构造函数,避免外部类调用
     46      */
     47     private PrototypeManager(){
     48     }
     49     /**
     50      * 添加原型
     51      * @param protoName 原型的名字
     52      * @param prototype 原型的实例
     53      */
     54     public synchronized static void setPrototype(String protoName,Prototype prototype){
     55         map.put(protoName, prototype);
     56     }
     57     /**
     58      * 获得原型
     59      * @param protoName 原型的名字
     60      * @return 返回原型的实例
     61      * @throws Exception 如果找不到,则跑出找不到异常
     62      */
     63     public synchronized static Prototype getPrototype(String protoName) throws Exception{
     64         Prototype prototype = map.get(protoName);
     65         if(prototype == null){
     66             throw new Exception("no "+protoName+" in Manager");
     67         }
     68         return prototype;
     69     }
     70     /**
     71      * 从管理器中删除原型的实例
     72      * @param protoName 原型的名字
     73      */
     74     public synchronized static void removedPrototype(String protoName){
     75         map.remove(protoName);
     76     }
     77 }
     78 /**
     79  * 原型的使用者
     80  * @author xingoo
     81  *
     82  */
     83 public class Client {
     84     public static void main(String[] args){
     85         try{
     86             /**
     87              * 创建一种原型的实现,放入管理器中
     88              */
     89             Prototype p1 = new ConcretePrototype1();
     90             System.out.println("p1 "+p1);
     91             PrototypeManager.setPrototype("MyPrototype", p1);
     92             
     93             Prototype prototype1 = PrototypeManager.getPrototype("MyPrototype").clone();
     94             System.out.println("prototype1 "+prototype1);
     95             /**
     96              * 切换成另一种原型的实现,修改管理器中的对象
     97              */
     98             Prototype p2 = new ConcretePrototype1();
     99             System.out.println("p2 "+p2);
    100             PrototypeManager.setPrototype("p1", p2);
    101             
    102             Prototype prototype2 = PrototypeManager.getPrototype("MyPrototype").clone();
    103             System.out.println("prototype2 "+prototype2);
    104             /**
    105              * 注销该原型实现,对象使用后,观察情况
    106              */
    107             PrototypeManager.removedPrototype("MyPrototype");
    108             
    109             Prototype prototype3 = PrototypeManager.getPrototype("MyPrototype").clone();
    110             System.out.println("prototype3 "+prototype3);
    111             
    112         }catch(Exception e){
    113             e.printStackTrace();
    114         }
    115     }
    116 }

      运行结果

    p1 com.xingoo.test1.ConcretePrototype1@116ab4e
    prototype1 com.xingoo.test1.ConcretePrototype1@129f3b5
    p2 com.xingoo.test1.ConcretePrototype1@13f3045
    prototype2 com.xingoo.test1.ConcretePrototype1@17a29a1
    java.lang.Exception: no MyPrototype in Manager
        at com.xingoo.test1.PrototypeManager.getPrototype(Client.java:66)
        at com.xingoo.test1.Client.main(Client.java:109)
  • 相关阅读:
    linux centos7 防止暴力破解
    win10 配置git 环境变量
    Tengine的说明
    php composer 报错 requires php ^7.1.8 || ^8.0 -> your php version
    uni-app v-for循环遍历 动态切换class、动态切换style
    Tomcat安装与配置
    我的云服务之WWW
    RHEL7 单独安装图形 X11
    python3-sql解析库——sqlparse
    Python3实战——爬虫入门
  • 原文地址:https://www.cnblogs.com/xing901022/p/4050910.html
Copyright © 2011-2022 走看看