原型模式(Prototype)解析例子

简介:
摘要:本文深入浅出的讲述了设计模式中的 原型 模式 , 并给出了简单的示例 , 例子浅显易懂 , 并附带源代码。
       原型模式属于创建型模式,其意图是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这就要求可以通过复制的方法复制一个对象。定制一个通用的图形编辑器框架,编辑器框架可能有一个工具选择板用以将这些图形对象添加到画布上,这个选择板还可能包括选择,移动,和其他操纵音乐对象的工具。用户可以点击选择板上的按钮来画一个图形,或者用户可以选择一个图形移动。这里的关键是定义一个抽象的类,每个选择板上的图形都实现此类的抽象方法,如:选择板上有一个画矩形图形的按钮,当选择这个按钮在画布上点击时,便画出一个图形。解决办法是通过克隆一个矩形的实例来创建新的图形,被克隆的矩形就是原型模式的原型。画出来的矩形通过调整大小参数,移动位置最终达到用户的需求。
   
适用性:
        当一个系统应该独立于他的产品创建,构成和表示时,要使用 Prototype 模式,以及
当要实例化的类是在运行时刻指定的,或者为了避免创建一个与产品类层次平行的工厂类层次时,或者当一个类的实例只能有几个不同状态组合的一种时。建立相应数目的原型并克隆他们可能比每次用合适的状态手工实例化该类更方便一些。
 
例如:有一个画板( toolbar )可以从中取到两种图形:圆型( circle )和矩形( rectangle )它们都属于原型( Prototype , 当客户需要画一个图形时便从画板中去一个图形,原型模式的关键就在于画板克隆一个图形对象,然后返回给客户。
                 图 1 原型模式的 UML
参与者:
    Prototype: 声明一个克隆自身的接口。
    ConcretePrototye(Circle): 实现一个克隆自身的操作。
    Client: 让一个原型克隆自身从而创建一个新的对象。
使用 Prototype 有以下的效果:
l          运行时刻增加和删除产品,原型模式允许只通过客户注册原型实例就可以将一个新的具体产品并入系统,
l          改变值以指定新对象   高度动态的系统允许你通过对象复合定义新的行为。
l          改变结构以指定新对象   许多应用由部件和子部件来创建对象,这样的应用通常允许你实例化复杂的,用户定义的结构。
l          减少子类的构造
l          用类动态配置应用   一些运行时刻环境允许你动态将类类装载到应用中。
Prototype 的主要缺陷是每一个 Prototype 的子类都必须实现 Clone 操作,这可能困难,当内部包括一个不支持拷贝或者有循环引用的对象时,实现克隆可能也会困难。
具体代码:
Prototype 代码:
package  prototype;
public   interface  Prototype  extends  Cloneable{
     public  Object clone();
     public  String getName();
}
Rectangle 代码:
package  prototype;
public   class  Rectangle  implements  Prototype,Command{
     public  Object clone(){
       Object clone= null ;
        try {
           clone= super .clone();
       } catch (CloneNotSupportedException e){
           System. err .println( "Clone not supported!" );
       }
        return  clone;
    }
     public  String getName(){
        return   "Rectangle" ;
    }
     public   void  draw(){
       System. out .println( "Draw a rectangle" );
    }
}
Circle 代码:
package  prototype;
public   class  Circle  implements  Prototype,Command{
     public  Object clone(){
       Object clone= null ;
        try {
           clone= super .clone();
       } catch (CloneNotSupportedException e){
           System. err .println( "Colone not support!" );
       }
        return  clone;
    }
     public  String getName(){
        return   "circle" ;
    }
     public   void  draw(){
       System. out .println( "Draw a circle" );
    }
}
Command 代码;
package  prototype;
public   interface  Command{
     public   void  draw();
}
Toolbar 代码:
package  prototype;
import  java.util.HashMap;
public   class  Toolbar{
     private  HashMap  tools = null ;
     public  Toolbar(){
        tools  =  new  HashMap();
        tools .put( "circle" , new  Circle());
        tools .put( "rectangle" , new  Rectangle());      
    }
     public  Object getClone(String key){
       Object obj =  tools .get(key);
        if (obj!= null ) return  ((Prototype)obj).clone();
        return   null ;
    }
}
Client 代码:
package  prototype;
public   class  Client{
     public   static   void  main(String[] args){
       Toolbar tb =  new  Toolbar();
       Command c=(Command)tb.getClone( "circle" );
        c.draw();
       c=(Command)tb.getClone( "rectangle" );
       c.draw();
      
    }
}
总结:原型模式在生成复杂对象比较苦难的环境中比较适用,通过克隆已有对象来实现创建新的对象,节省了时间和空间。
本文转自凌辉博客51CTO博客,原文链接http://blog.51cto.com/tianli/40705如需转载请自行联系原作者

lili00okok
相关文章
|
7月前
|
Java
原型模式的用法
原型模式的用法
30 0
|
8月前
|
前端开发
前端原型和原型链构造函数的使用
前端原型和原型链构造函数的使用
55 0
|
8月前
|
前端开发
前端原型和原型链构造函数的使用
前端原型和原型链构造函数的使用
48 0
|
4月前
|
JavaScript 前端开发 Java
JavaScript难点:原型、原型链、继承、new、prototype和constructor
JavaScript 不像 Java、C++ 这种纯面向对象的语言,可以通过类实现继承,JavaScript中的继承是通过原型实现的,即使 ES6 中新增的 class 类也只是原型的语法糖而已
47 4
|
8月前
|
前端开发
前端原型和原型链constructor
前端原型和原型链constructor
57 0
|
前端开发
前端学习案例1-原型&原型链&构造函数
前端学习案例1-原型&原型链&构造函数
31 0
前端学习案例1-原型&原型链&构造函数
|
前端开发
前端学习案例2-原型&原型链&构造函数2
前端学习案例2-原型&原型链&构造函数2
35 0
前端学习案例2-原型&原型链&构造函数2
|
前端开发
前端学习案例3-原型&原型链&构造函数3
前端学习案例3-原型&原型链&构造函数3
34 0
前端学习案例3-原型&原型链&构造函数3
|
前端开发
前端学习案例1-原型&原型链&构造函数1
前端学习案例1-原型&原型链&构造函数1
48 0
前端学习案例1-原型&原型链&构造函数1
|
JavaScript 前端开发
面试向:原型、原型链、构造函数、继承、实例对象
面试向:原型、原型链、构造函数、继承、实例对象
面试向:原型、原型链、构造函数、继承、实例对象