`

10 Prototype 模式

 
阅读更多

Prototype 模式

您从图书馆的期刊从发现了几篇您感兴趣的文章,由于这是图书馆的书,您不可以直接在书中作记号或写字,所以您将当中您所感兴趣的几个主题影印出来,这下子您就可在影印的文章上画记重点。

Prototype模式的作用有些类似上面的描述,您在父类别中定义一个clone()方法,而在子类别中重新定义它,当客户端对于所产生的物件有兴趣并想加以利用,而您又不想破坏原来的物件,您可以产生一个物件的复本给它。

Prototype具有展示的意味,就像是展览会上的原型车款,当您对某个车款感兴趣时,您可以购买相同款示的车,而不是车展上的车。

在软体设计上的例子会更清楚的说明为何要进行物件复制,假设您要设计一个室内设计软体,软体中有一个展示家具的工具列,您只要点选工具列就可以产生一个家 具复本,例如一张椅子或桌子,您可以拖曳这个复制的物件至设计图中,随时改变它的位置、颜色等等,当您改变设计图中的物件时,工具列上的原型工具列是不会 跟着一起改变的,这个道理是无需解释的。

下面的 UML 类别图表示了上述的简单概念:



 

Prototype模式的重点在于clone(),它负责复制物件本身并传回,但这个clone()本身在实作上存在一些困难,尤其是当物件本身又继承另一个物件时,如何确保复制的物件完整无误,在不同的程式语言中有不同的作法。

在Java中的作法是透过实作一个Cloneable介面,它只是一个声明的介面,并无规定任何实作的方法,您的目的是改写Object的clone ()方法,使其具备有复制物件的功能,这个方面建议您参考:How to avoid traps and correctly override methods from java.lang.Object。

用一个简单的例子来实作上图中的结构,这个例子利用了Java语言本身的clone特性:
AbstractFurniture.java

public abstract class AbstractFurniture 
                             implements Cloneable {
    public abstract void draw();
    
    // 在Design Pattern上,以下的clone是抽象未实作的
    // 实际上在Java中class都继承自Object
    // 所以在这边我们直接重新定义clone() 
    // 这是为了符合Java现行的clone机制
    protected Object clone() throws CloneNotSupportedException { 
        return super.clone(); 
    }
}

 

CircleTable与SquareTable继承了AbstractFurniture,并实作clone方法,用于传回本身的复制品:
CircleTable.java

import java.awt.*;

public class CircleTable extends AbstractFurniture {
    protected Point center;    
    
    public void setCenter(Point center) {
        this.center = center;
    }
    
    protected Object clone () 
                     throws CloneNotSupportedException { 
        Object o = super.clone(); 
        if(this.center != null) {
            ((CircleTable) o).center = (Point) center.clone();
        }
        
        return o; 
    } 

    public void draw() { 
        System.out.println("\t圆桌\t中心:(" + center.getX() 
                            + ", " + center.getY()+ ")");
    } 
}

 SquareTable.java

import java.awt.*;

public class SquareTable extends AbstractFurniture {
    protected Rectangle rectangle;    
    
    public void setRectangle(Rectangle rectangle) {
        this.rectangle = rectangle;
    }
    
    protected Object clone () 
                      throws CloneNotSupportedException { 
        Object o = super.clone(); 
        if(this.rectangle != null) { 
            ((SquareTable) o).rectangle = (Rectangle) rectangle.clone();
        }
        
        return o; 
    } 

    public void draw() { 
        System.out.print("\t方桌\t位置:(" + rectangle.getX() 
                            + ", " + rectangle.getY()+ ")");
        System.out.println(" / 宽高:(" + 
                         rectangle.getWidth() 
                + ", " + rectangle.getHeight()+ ")");
    }
}

 House是个虚拟的房屋物件,从Prototype复制出来的物件加入至House中:
House.java

import java.util.*;

public class House { 
    private Vector vector;

    public House() { 
        vector = new Vector(); 
    }

    public void addFurniture(AbstractFurniture furniture) { 
        vector.addElement(furniture); 
        
        System.out.println("现有家具....");
        
        Enumeration enumeration = vector.elements();
        while(enumeration.hasMoreElements()) { 
             AbstractFurniture f = 
                 (AbstractFurniture) enumeration.nextElement(); 
             f.draw(); 
        } 
        System.out.println(); 
    } 
}

 再来是应用程式本身:
Application.java

import java.awt.*;

public class Application {
    private AbstractFurniture circleTablePrototype;
    
    public void setCircleTablePrototype(
                   AbstractFurniture circleTablePrototype) {
        this.circleTablePrototype = circleTablePrototype;
    }
    
    public void runAppExample() throws Exception {
        House house = new House(); 
        CircleTable circleTable = null;

        // 从工具列选择一个家具加入房子中
        circleTable =
            (CircleTable) circleTablePrototype.clone();
        circleTable.setCenter(new Point(10, 10));
        house.addFurniture(circleTable); 
        
        // 从工具列选择一个家具加入房子中
        circleTable = 
            (CircleTable) circleTablePrototype.clone();
        circleTable.setCenter(new Point(20, 30));
        house.addFurniture(circleTable); 
    }
    
    public static void main(String[] args) throws Exception {
        Application application = new Application();
        application.setCircleTablePrototype(
                            new CircleTable());
        application.runAppExample();
    }
}

 Java中的clone()方法是继承自Object,AbstractFurniture的子类别则override这个clone()方法,以复制其本身并传回。

下图为Prototype模式的类别结构图:



 在 Gof 的设计模式书中给出一个原型模式的应用:一个通用的图型编辑器 Framework。在这个 Framework中有一个工具列,您可以在上面选择音乐符号以加入乐谱中,并可以随时调整音乐符号的位置等等。

图型编辑器Framework是通用的,然而它并不知道这些音乐符号的型态,有人或许会想到继承图型编辑器Framework来为每个音乐符号设计一个框 架子类别,但由于音乐符号的种类很多,这会产生相当多的子类别,为了避免这种情况,可以透过Prototype模式来减少子类别的数目,可以设计出以下的 结构:



 依照这个结构,图型编辑器的Framework可以独立于要套用的特定类别之外,虽然不知道被复制传回的对象型态是什么,但总可以按照 Graphics所定义的介面来操作这些物件。

 

转自:http://www.riabook.cn/doc/designpattern/PrototypePattern.htm

  • 大小: 27.5 KB
  • 大小: 16.3 KB
  • 大小: 24.5 KB
分享到:
评论

相关推荐

    Prototype模式

    **原型模式(Prototype Pattern)**是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,而不是通过构造函数。在某些情况下,当创建新对象的成本非常高时(例如,对象需要大量的初始化操作或者从...

    设计模式 创建型模式 Prototype模式(原型)

    Prototype模式 即原型模式,提供一个已经存在的对象进行新对象创建的接口,一般情况下都是使用Clone接口。 此模式非常简单,简单的说就是复制多个当前对象供使用。Prototype模式允许一个对象再创建另外一个可定制...

    23种设计模式之Prototype模式代码

    **原型模式(Prototype模式)**是软件设计模式中的一个经典模式,属于创建型模式。它提供了一种通过复制现有的对象来创建新对象的方式,而无需知道具体创建过程的细节。这种模式在需要频繁创建相似对象时非常有用,...

    Prototype模式练习

    在给定的"Prototype模式练习"中,我们可以深入探讨这种模式的应用和实现。 首先,原型模式的核心在于`Cloneable`接口和`clone()`方法。在Java中,当一个类实现了`Cloneable`接口,并且重写了`Object`类中的`clone()...

    设计模式之Prototype(原型)

    Prototype模式的核心在于实现克隆操作。在Java中,我们可以利用`Cloneable`接口和`clone()`方法来实现对象的复制。但是需要注意,不是所有类都能直接使用`clone()`方法,因为默认的`clone()`方法仅复制对象的引用,...

    原型设计模式prototype

    **原型设计模式(Prototype Pattern)**是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而不是通过构造函数来实例化新对象。在面向对象编程中,当我们需要频繁地创建具有相同或相似属性的对象时,...

    C++设计模式代码资源10_prototype.zip

    这个"C++设计模式代码资源10_prototype.zip"压缩包显然包含了关于C++实现原型模式的示例代码。 原型模式的核心概念是克隆(Cloning)。在C++中,克隆能力可以通过实现`clone()`方法来赋予一个类。这个方法会返回一...

    Prototype Pattern原型模式

    **原型模式(Prototype Pattern)**是一种基于克隆的创建型设计模式,它的主要目的是为了提高创建新对象的效率,特别是当创建新对象的过程复杂或者资源消耗较大时。在原型模式中,一个已经创建的对象(称为原型)被...

    设计模式之Prototype

    在Prototype模式中,核心概念包括“原型”接口或抽象类,以及具体的可克隆的实现类。原型接口规定了克隆操作,而实现类则提供了实际的克隆功能。通常,克隆操作有两种形式:浅克隆(Shallow Clone)和深克隆(Deep ...

    (创建型模式)Prototype模式

    **原型模式(Prototype模式)**是软件设计模式中的创建型模式之一,它在23种GOF设计模式中占据重要地位。原型模式的核心思想是通过复制已有对象来创建新对象,而不是从头开始创建,从而提高代码的效率和可扩展性。这种...

    Prototype开发和使用

    在软件开发领域,Prototype模式是一种设计模式,它主要应用于创建对象。该模式的主要目的是减少对象的创建开销,特别是在需要大量相似对象时。 Prototype模式通过克隆已存在的对象来创建新对象,而不是从头开始构造...

    设计模式C++学习之原型模式(Prototype)

    本篇文章将深入探讨“原型模式(Prototype)”这一经典的设计模式,它是面向对象设计的一个重要概念,尤其在C++编程中有着广泛的应用。 原型模式是一种创建型设计模式,它的核心思想是通过复制已有对象来创建新对象,...

    原型模式prototype

    **原型模式(Prototype)**是软件设计模式中的一种,它属于创建型模式,主要用于简化对象的创建过程,通过复制已有对象来生成新对象,避免了重复的构造过程,提高了代码的效率和可维护性。在Java、C#等面向对象语言...

    创建型模式之原型模式(Prototype Pattern)

    **原型模式(Prototype Pattern)详解** 在软件设计中,原型模式是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,避免了重复的构造过程,提高了代码的效率和可维护性。原型模式的核心思想...

    原型模式(Prototype)

    **原型模式(Prototype)** 原型模式是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,而不是通过传统的构造函数。这种模式在系统中需要创建大量相似对象时特别有用,可以提高效率并减少内存...

    prototype原型模式

    - `prototype.pro` 是Qt项目文件,用于编译和构建原型模式的示例。 - `readme.txt` 可能是项目说明文件,包含关于如何运行和理解代码的指导。 - `mainwindow.ui` 是Qt Designer生成的用户界面描述文件,描述了GUI的...

    c++-设计模式之原型模式(Prototype Pattern)

    原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而不是通过类构造器。这种模式常用于需要频繁创建相似对象的场景,能够提高性能并减少内存使用。 原型模式的组成 原型接口...

    prototype_1.7.3.js 最新版本

    《prototype_1.7.3.js:JavaScript框架的里程碑》 在JavaScript的世界里,Prototype库是一个不可或缺的重要组成部分,尤其在Web开发领域,它为开发者提供了强大的功能和便利性。Prototype_1.7.3.js是这个库的一个...

    设计模式 t05Prototype

    "设计模式 t05Prototype" 标题暗示我们将讨论的是原型(Prototype)设计模式,它是创建型设计模式的一种,主要用在对象复制或克隆的场景。 原型模式的核心思想是通过复制一个已经存在的对象来创建新对象,而不是...

    prototype帮助中文文档

    此外,了解并熟练使用Prototype提供的工具和模式,如观察者模式(Observer)和委托(Delegation),可以提高代码的可维护性和性能。 综上所述,Prototype 是一个强大而全面的JavaScript库,尤其适用于构建富互联网...

Global site tag (gtag.js) - Google Analytics