美文网首页
设计模式-原型模式(四)

设计模式-原型模式(四)

作者: 巨子联盟 | 来源:发表于2018-05-22 09:16 被阅读0次
    • 什么是原型模式

    简单来讲就是根据一个原型对象复制另外一个对象,和孙悟空变身一样.
    原始模型模式允许动态的增加或减少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构
    缺点是每一个类都必须配备一个克隆方法
    在java实现原型模式主要是覆写clone方法
    举例如下:
    声明一个接口,继承自Cloneable

    package com.byedbl.prototype.mypackage;/*
     * A Graphic Interface ( A prototype interface )
     */
    import java.io.*;
    
    public interface IGraphic extends Cloneable, Serializable {
        public String getName() ;
        public void setName(String gName);
    }
    

    再创建一个抽象类,里面提供一个clone方法,clone方法返回一个新的实例,这里简单的调用父类的clone方法

    package com.byedbl.prototype.mypackage;/*
     * An Abstract Graphic Class ( Prototype )
     */
    import java.lang.*;
    import java.io.*;
    
    public abstract class Graphic implements IGraphic {
        private String name;
        
        public Object clone() {
            try {
                return super.clone();
            } catch (CloneNotSupportedException e){
                System.out.println("Do not support clone !!!");
                throw new InternalError();
            }
        }
       
        public String getName() {
            return name;
        }
        
        public void setName(String gName) {
            name = gName;
        }
    
        public abstract void doSomething();
    }
    

    再创建两个实现类

    package com.byedbl.prototype.mypackage;
    
    import com.byedbl.prototype.mypackage.Graphic;
    
    /*
     *  A concrete prototype to draw a line
     */
    public class LineSymbol extends Graphic {
        public LineSymbol() {
        }
    
        public void doSomething() {
            System.out.println("I am used to draw a line !");
        }
    }
    
    package com.byedbl.prototype.mypackage;
    
    import com.byedbl.prototype.mypackage.Graphic;
    
    /*
     *  A concrete prototype to draw a note
     */
    public class NoteSymbol extends Graphic {
        public NoteSymbol() {
        }
    
        public void doSomething() {
            System.out.println("I am used to draw a note !");
        }
    }
    

    缓存类:

    package com.byedbl.prototype;/*
     *  A Symbol Loader to register all prototype instance
     */
    import com.byedbl.prototype.mypackage.Graphic;
    import com.byedbl.prototype.mypackage.LineSymbol;
    import com.byedbl.prototype.mypackage.NoteSymbol;
    
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class SymbolLoader  {
        private Map<String, Graphic> symbols = new ConcurrentHashMap<>();
        public SymbolLoader() {
               symbols.put("Line", new LineSymbol());
               symbols.put("Note", new NoteSymbol());
        }
        public Map<String, Graphic> getSymbols() {
            return symbols;
        }
    }
    

    客户端测试代码

            public static void main(String[] args) {
            //-----  Initial our prototype instance  ----------
            SymbolLoader myLoader = new SymbolLoader();
            Map<String,Graphic> mySymbols = myLoader.getSymbols();
    
            //-----  Draw a Line  -------------------------------
            Graphic myLine = (Graphic)((Graphic)mySymbols.get("Line")).clone();
            myLine.doSomething();
        }
    

    为什么要一个缓存类呢?因为当new一个对象很复杂,很好资源时,我们可以将已经创建好的缓存起来,这样每次用的时候只要拷贝一个就可以了.

    那原型模式适合什么场景呢?
    1. 资源优化场景。
    2. 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
    3. 性能和安全要求的场景。
    4. 通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 5. 一个对象多个修改者的场景。
    5. 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
    6. 在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者
    克隆应该满足的3个条件
    1. x.clone() != x
    2. x.clone().getClass() == x.getClass
    3. x.clone.equals(x) (非必选)

    注意
    复制有深复制和浅复制,浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。深复制要深入多少层,这是个不容易确定的问题,可能出现循环引用问题.

    相关文章

      网友评论

          本文标题:设计模式-原型模式(四)

          本文链接:https://www.haomeiwen.com/subject/dcjqjftx.html