SlideShare uma empresa Scribd logo
1 de 64
设计模式 - 组合
( composite )模式
组合模式
 模式动机与定义
 模式结构与分析
 模式实例与解析
 模式效果与应用
 模式扩展
模式动机
 对于树形结构,当容器对象(如文件夹)的某一个
方法被调用时,将遍历整个树形结构,寻找也包含
这个方法的成员对象(可以是容器对象,也可以是
叶子对象,如子文件夹和文件)并调用执行。
 由于容器对象和叶子对象在功能上的区别,在使用
这些对象的客户端代码中必须有区别地对待容器对
象和叶子对象,而实际上大多数情况下客户端希望
一致地处理它们,因为对于这些对象的区别对待将
会使得程序非常复杂。
模式动机
组合模式描述了如何将容器对象和叶子对象
进行递归组合,使得用户在使用时无需对它
们进行区分,可以一致地对待容器对象和叶
子对象,这就是组合模式的模式动机。
模式定义
 组合模式 (Composite Pattern) :组合多个
对象形成树形结构以表示“整体—部分”的
结构层次。组合模式对单个对象(即叶子
对象)和组合对象(即容器对象)的使用
具有一致性。
 组合模式又可以称为“整体—部分” (Part-
Whole) 模式,属于对象的结构模式,它将
对象组织到树结构中,可以用来描述整体
与部分的关系。
模式结构
children
Client
Component
+
+
+
+
operation ()
add (Component c)
remove (Component c)
getChild (int i)
...
Leaf
+ operation ()
...
Composite
+
+
+
+
operation ()
add (Component c)
remove (Component c)
getChild (int i)
...
for(Component child:children)
{
child.operation();
}
模式结构
 组合模式包含如下角色:
Component: 抽象构件
Leaf: 叶子构件
Composite: 容器构件
Client: 客户类
模式分析
 组合模式的关键是定义了一个抽象构件类,
它既可以代表叶子,又可以代表容器,而客
户端针对该抽象构件类进行编程,无需知道
它到底表示的是叶子还是容器,可以对其进
行统一处理。
 同时容器对象与抽象构件类之间还建立一个
聚合关联关系,在容器对象中既可以包含叶
子,也可以包含容器,以此实现递归组合,
形成一个树形结构。
文件系统组合模式结构图
list
AbstractElement
{abstract}
+
+
+
+
add (AbstractElement element)
remove (AbstractElement element)
get (int i)
method ()
...
: void
: void
: AbstractElement
: void
File
+ method ()
...
: void
Folder
- list : AbstractElement[]
+
+
+
+
add (AbstractElement element)
remove (AbstractElement element)
get (int i)
method ()
...
: void
: void
: AbstractElement
: void
叶子节点的代码
容器构件角色代码
文件浏览
文件有不同类型,不同类型的文件其浏览
方式有所区别,如文本文件和图片文件的
浏览方式就不相同。对文件夹的浏览实际
上就是对其中所包含文件的浏览,而客户
端可以一致地对文件和文件夹进行操作,
无需关心它们的区别。使用组合模式来模
拟文件的浏览操作。
组合模式实例
 文件浏览 fileList
AbstractFile
{abstract}
+
+
+
add (AbstractFile element)
remove (AbstractFile element)
display ()
...
: void
: void
: void
ImageFile
- fileName : String
+
+
+
+
ImageFile (String fileName)
add (AbstractFile element)
remove (AbstractFile element)
display ()
...
: void
: void
: void
Folder
-
-
fileList
fileName
: ArrayList
: String
+
+
+
+
Folder (String fileName)
add (AbstractFile element)
remove (AbstractFile element)
display ()
...
: void
: void
: void
TextFile
- fileName : String
+
+
+
+
TextFile (String fileName)
add (AbstractFile element)
remove (AbstractFile element)
display ()
...
: void
: void
: void
VideoFile
- fileName : String
+
+
+
+
VideoFile (String fileName)
add (AbstractFile element)
remove (AbstractFile element)
display ()
...
: void
: void
: void
模式优缺点
 组合模式的优点如下:
可以清楚地定义分层次的复杂对象,
表示对象的全部或部分层次,使得增
加新构件也更容易。
客户端调用简单,客户端可以一致的
使用组合结构或其中单个对象。
模式优缺点
定义了包含叶子对象和容器对象的类层
次结构,叶子对象可以被组合成更复杂
的容器对象,而这个容器对象又可以被
组合,这样不断递归下去,可以形成复
杂的树形结构。
很容易在组合体内加入对象构件,客户
端不必因为加入了新的对象构件而更改
原有代码。
模式优缺点
 组合模式的缺点如下:
使设计变得更加抽象,对象的业务规
则如果很复杂,则实现组合模式具有
很大挑战性,而且不是所有的方法都
与叶子对象子类都有关联。
增加新构件时可能会产生一些问题,
很难对容器中的构件类型进行限制。
模式适用环境
在以下情况下可以使用组合模式:
 需要表示一个对象整体或部分层次,在具有整体
和部分的层次结构中,希望通过一种方式忽略整
体与部分的差异,可以一致地对待它们。
 让客户能够忽略不同对象层次的变化,客户端可
以针对抽象构件编程,无需关心对象层次结构的
细节。
 对象的结构是动态的并且复杂程度不一样,但客
户需要一致地处理它们。
XML 文档解析
<?xml version="1.0"?>
<books>
<book>
<author>Carson</author>
<price format="dollar">31.95</price>
<pubdate>05/01/2001</pubdate>
</book>
<pubinfo>
<publisher>MSPress</publisher>
<state>WA</state>
</pubinfo>
</books>
模式应用
操作系统中的目录结构是一个树形结构,
因此在对文件和文件夹进行操作时可以应
用组合模式,例如杀毒软件在查毒或杀毒
时,既可以针对一个具体文件,也可以针
对一个目录。如果是对目录查毒或杀毒,
将递归处理目录中的每一个子目录和文件
模式应用
JDK 的 AWT/Swing 是组合模式在 Java 类库中的一个
典型实际应用。
component
Component
Button Container
- component : Component[]
TextComponentCheckbox
组合模式用于组合多个对象形成树形结构以表示“整体——部分”的结构层
次。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使
用具有一致性。组合模式又可以称为“整体——部分”模式,属于对象的结
构模式,它将对象组织到树结构中,可以用来描述整体与部分的关系。
组合模式包含三个角色:抽象构件为叶子构件和容器构件对象声明接口,
在该角色中可以包含所有子类共有行为的声明和实现;叶子构件在组合结
构中表示叶子节点对象,叶子节点没有子节点;容器构件在组合结构中表
示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可
以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定
义的行为。
组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代
表容器,而客户端针对该抽象构件类进行编程,无需知道它到底表示的是
叶子还是容器,可以对其进行统一处理。
组合模式的主要优点在于可以方便地对层次结构进行控制,客户
端调用简单,客户端可以一致的使用组合结构或其中单个对象,
用户就不必关心自己处理的是单个对象还是整个组合结构,简化
了客户端代码;其缺点在于使设计变得更加抽象,且增加新构件
时可能会产生一些问题,而且很难对容器中的构件类型进行限制
。
组合模式适用情况包括:需要表示一个对象整体或部分层次;让
客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编
程,无需关心对象层次结构的细节;对象的结构是动态的并且复
杂程度不一样,但客户需要一致地处理它们。
组合模式根据抽象构件类的定义形式,又可以分为透明组合模式
和安全组合模式。
备忘录模式
 忘 模式概述备 录
 忘 模式的 与备 录 结构 实现
 忘 模式的 用 例备 录 应 实
 多次撤实现 销
 忘 模式的 缺点与适用 境备 录 优 环
备忘录模式——软件中的“后悔药”——撤
销 (Undo)
备忘录模式概述
分析
 通过使用备忘录模式可以让系统恢复到某一
特定的历史状态
 首先保存软件系统的历史状态,当用户需要
取消错误操作并且返回到某个历史状态时,
可以取出事先保存的历史状态来覆盖当前状
态
备忘录模式的定义
备忘录模式
 提供了一种状态恢复的实现机制,使得用户
可以方便地回到一个特定的历史步骤
 当前在很多软件所提供的撤销 (Undo) 操作
中就使用了备忘录模式
备忘录模式的结构
mementoreturn new Memento(state);
Originator
- state :
+
+
RestoreMemento (Memento m)
CreateMemento ()
...
Memento
- state :
+
+
GetState ()
SetState ( state)
...
Caretaker
state=m.GetState();
备忘录模式的结构
 备忘录模式包含以下 3 个角色:
• Originator (发起人) : 记录当前时刻的内部状
态,负责定义哪些属于备份范围的状态,负责创
建和恢复备忘录数据。
• Memento (备忘录 ): 负责存储发起人对象的内
部状态,在需要的时候提供发起人需要的内部状
态。
• Caretaker (负责人) : 对备忘录进行管理,保
存和提供备忘录。
动机
 有时候用户需要撤销多步操作
 实现方案:在负责人类中定义一个集合来存
储多个备忘录,每个备忘录负责保存一个历
史状态,在撤销时可以对备忘录集合进行逆
向遍历,回到一个指定的历史状态,还可以
对备忘录集合进行正向遍历,实现重做
(Redo) 或恢复操作,即取消撤销,让对象
状态得到恢复
备忘录模式的优缺点
模式优点
 提供了一种状态恢复的实现机制,使得用户
可以方便地回到一个特定的历史步骤
 实现了对信息的封装,一个备忘录对象是一
种原发器对象状态的表示,不会被其他代码
所改动
模式缺点
 资源消耗过大,如果需要保存的原发器类的
成员变量太多,就不可避免地需要占用大量
的存储空间,每保存一次对象的状态都需要
消耗一定的系统资源
模式适用环境
 保存一个对象在某一个时刻的全部状态或部
分状态,这样以后需要时能够恢复到先前的
状态,实现撤销操作
 防止外界对象破坏一个对象历史状态的封装
性,避免将对象历史状态的实现细节暴露给
外界对象
建造者模式
建造者模式的由来
在软件系统中,有时候面临着“一个复杂
对象”的创建工作,其通常由各个部分的
子对象用一定的算法构成;
这个复杂对象的各个部分经常面临着
剧烈的变化,但是将它们组合在一起的
算法却相对稳定。
在实际生活中,也有这样的例子:
譬如一个房屋的构建。创建过程基本
不变 , 但是门窗等组件却是易变的。
建造者模式的由来
如何应对这种变化?如何提供一种“封装机
制”来隔离出“复杂对象的各个部分”的变化
,从而保持系统中的“稳定构建算法”不随
着需求改变而改变?这就是要说的建造者
模式。
模式的意图
将一个复杂的构建与其表示相分离,
使得同样的构建过程可以创建不同的表示
。
建造者模式的意图和适用性
以下情况可以使用建造者模式:
1. 需要生成的产品对象有复杂的内部结
构。
2. 创建复杂对象的算法稳定,或建造者
模式可以强迫生成一定的顺序。
3. 当构造过程允许被构造的对象有不同
的表示时。
建造者模式结构图
建造者模式的结构和参与者
1 ) Builder
为创建一个 Product 对象的各个部件指定抽象接口。
2 ) ConcreteBuilder
实现 Builder 的接口以构造和装配该产品的各个部件。
定义并明确它所创建的表示。
提供一个检索产品的接口
3 ) Director
构造一个使用 Builder 接口的对象。
4 ) Product
表示被构造的复杂对象。 ConcreteBuilder 创建该产品的内部表
示并定义它的装配过程。
包含定义组成部件的类,包括将这些部件装配成最终产品的接口
。
设计游戏场景中的房屋
假设房屋由五个部分组成:地板、墙壁
、窗户、门和天花板。
构建一个房屋的步骤是一定的,而具体
的组件(门、窗等)是易变的。
采用建造者模式分离易变组件和稳定的
构建过程。
优缺点
1. 建造者模式的使用使得产品的内部表象可以独立的变化。使用
建造者模式可以使客户端不必知道产品内部组成的细节。
2. 每一个 Builder 都相对独立,而与其它的 Builder 无关。
可使对构造过程更加精细控制。
4. 将构建代码和表示代码分开。
5. 建造者模式的缺点在于难于应付“分步骤构建算法”的需求变动
( 如果创建算法总是变化就不适用了 ) 。
设计模式 – 原型( Prototype )模式
原型( Prototype )模式
通过给出一个原型对象来指明所要创建的对象类型,然后用
拷贝这个原型对象的办法创建出更多的同类型对象。
孙大圣的毫毛
孙悟空在与黄风怪的战斗中,“使一个身外身的手段:把毫
毛揪下一把,用口嚼得粉碎,望上一喷,叫声‘变’,变有百
十个行者,都是一样得打扮,各执一根铁棒,把那怪围在空
中。”换而言之,孙悟空可以根据自己的形象,拷贝出很多
“身外身”来。
孙悟空这种身外身的手段在面向对象设计领域里叫原型
( Prototype )模式。
1 , Java 对原型模式的支持
在 Java 里面,我们可以通过 Clone() 方法实现原型模式。任何类
,只要想支持克隆,必须实现 Cloneable 接口。 Cloneable 接口
中有 Clone 方法,可以在类中复写实现自定义的克隆方法。克隆
的实现方法有三种:浅拷贝、深拷贝和完全拷贝。
(1) 浅拷贝
被拷贝对象的所有变量都含有与原来的对象相同的值,而所有的对
其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅拷贝所
考虑的对象,而不拷贝它所引用的对象。
(2) 深拷贝
被拷贝对象的所有变量都含有与原来的对象相同的值,除去那些
引用其他对象的变量。那些引用其他对象的变量将指向被拷贝过的
新对象,而不再是原有的那些被引用的对象。换言之,深拷贝把要
拷贝的对象所引用的对象都拷贝了一遍。
(3) 完全拷贝
完全拷贝不仅把要拷贝的对象所直接引用的对象都拷贝了一遍,
还把该对象间接引用到的所有对象也都拷贝了一遍。这是最彻底的
一种拷贝。
2 , Java 的 clone() 方法
Clone
protected Object clone() throws CloneNotSupportedException
This method may be called to create a new copy of the Object. The typical
behavior is as follows:
o == o.clone() is false
o.getClass() == o.clone().getClass() is true
o.equals(o) is true
However, these are not strict requirements, and may be violated if necessary. Of
the three requirements, the last is the most commonly violated, particularly if
the subclass does not override equals(Object) 55 .
If the Object you call clone() on does not implement Cloneable (which is a
placeholder interface), then a CloneNotSupportedException is thrown. Notice
that Object does not implement Cloneable; this method exists as a
convenience for subclasses that do.
Object's implementation of clone allocates space for the new Object using the
correct class, without calling any constructors, and then fills in all of the new
field values with the old field values. Thus, it is a shallow copy. However,
subclasses are permitted to make a deep copy.
All array types implement Cloneable, and override this method as follows (it
should never fail):
public Object clone() { try { super.clone(); } catch (CloneNotSupportedException
e) { throw new InternalError(e.getMessage()); } }
2 , Java 的 clone() 方法
⑴clone 方法将对象复制了一份并返回给调用者。一
般而言, clone ()方法满足:
① 对任何的对象 x ,都有 x.clone() !=x
克隆对象与原对象不是同一个对象
② 对任何的对象 x ,都有
x.clone().getClass()==x.getClass()
克隆对象与原对象的类型一样
③ 如果对象 x 的 equals() 方法定义恰当,那么
x.clone().equals(x) 应该成立。
⑵Java 中对象的克隆
① 为了获取对象的一份拷贝,我们可以利用 Object 类的
clone() 方法。
② 在派生类中覆盖基类的 clone() 方法,并声明为
public 。
③ 在派生类的 clone() 方法中,调用 super.clone() 。
3 , Java 的类拷贝实现代码
class Student implements Cloneable
{
     String name;
    int age;
     Student(String name,int age)
     {
        this.name=name;
        this.age=age;
     }
    public Object clone()
     {
         Object o=null;
        try
         {
         o=(Student)super.clone();//Object 中的 clone() 识别出你要复制的是哪一个对象。
         }
        catch(CloneNotSupportedException e)
         {
             System.out.println(e.toString());
         }
        return o;
     }
}
public static void main(String[] args)
     {
       Student s1=new Student(“zhangsan”,18);
       Student s2=(Student)s1.clone();
       s2.name=“lisi”;
      s2.age=20;
System.out.println(“name=”+s1.name+“,”+“age=”+s1.age);// 修改学生 2 后,不影响学生 1 的值。
    }
① 为什么我们在派生类中覆盖 Object 的 clone() 方法时,
一定要调用 super.clone() 呢?在运行时刻, Object 中的
clone() 识别出你要复制的是哪一个对象,然后为此对象
分配空间,并进行对象的复制,将原始对象的内容一一
复制到新对象的存储空间中。
②继承自 java.lang.Object 类的 clone() 方法是浅复制。
后面的代码可以证明。
浅拷贝
3 , Java 的类拷贝实现代码
class Professor
{
     String name;
    int age;
     Professor(String name,int age)
     {
        this.name=name;
        this.age=age;
     }
}
class Student implements Cloneable
{
     String name;// 常量对象。
     int age;
     Professor p;// 学生 1 和学生 2 的引用值都是
一样的。
     Student(String name,int age,Professor
p)
     {
        this.name=name;
        this.age=age;
        this.p=p;
     }
    public Object clone()
     {
         Student o=null;
        try
         {
             o=(Student)super.clone();
         }
        catch(CloneNotSupportedException e)
         {
             System.out.println(e.toString());
         }
         //o.p=(Professor)p.clone();
        return o;
     }
}
public static void main(String[] args)
     {
       Professor p=new Professor("wanGWu",50);
       Student s1=new Student("zhangsan",18,p);
       Student s2=(Student)s1.clone();
       s2.p.name="lisi";
      s2.p.age=30;
System.out.println("name="+s1.p.name+","+"age
="+s1.p.age);
// 学生 1 的教授为 lisi,age 为 30, 被改了
}
浅拷贝
3 , Java 的类拷贝实现代码
class Professor implements Cloneable
{
     String name;
    int age;
     Professor(String name,int age)
     {
        this.name=name;
        this.age=age;
     }
    public Object clone()
     {
         Object o=null;
        try
         {
             o=super.clone();
         }
        catch(CloneNotSupportedException e)
         {
             System.out.println(e.toString());
         }
        return o;
     }
}
class Student implements Cloneable
{
     String name;// 常量对象。
     int age;
     Professor p;// 学生 1 和学生 2 的引用值都是
一样的。
     Student(String name,int age,Professor
p)
     {
        this.name=name;
        this.age=age;
        this.p=p;
     }
    public Object clone()
     {
         Student o=null;
        try
         {
             o=(Student)super.clone();
         }
        catch(CloneNotSupportedException e)
         {
             System.out.println(e.toString());
         }
         o.p=(Professor)p.clone();
        return o;
     }
}
public static void main(String[] args)
     {
       Professor p=new Professor(“wanGWu”,50);
       Student s1=new Student(“zhangsan”,18,p);
       Student s2=(Student)s1.clone();
       s2.p.name=“lisi”;
      s2.p.age=30;
System.out.println(“name=”+s1.p.name+“,”+“age
=”+s1.p.age);// 学生 1 的教授不改变
}
深拷贝
3 , Java 的类拷贝实现代码
class Professor implements Serializable
{
     String name;
    int age;
     Professor(String name,int age)
     {
        this.name=name;
        this.age=age;
     }
}
class Student implements Serializable
{
     String name;// 常量对象。
     int age;
     Professor p;// 学生 1 和学生 2 的引用值都是一样的。
     Student(String name,int age,Professor p)
     {
        this.name=name;
        this.age=age;
        this.p=p;
     }
    public Object fullClone() throws IOException,
OptionalDataException,ClassNotFoundException
{
// 将对象写到流里
ByteArrayOutoutStream bo=new
ByteArrayOutputStream();
ObjectOutputStream oo=new
ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来
ByteArrayInputStream bi=new
ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
return(oi.readObject());
}
public static void main(String[] args)
     {
       Professor p=new Professor("wangwu",50);
       Student s1=new Student("zhangsan",18,p);
       Student s2=(Student)s1.fullClone();
       s2.p.name="lisi";
      s2.p.age=30;
System.out.println("name="+s1.p.name+","+"age
="+s1.p.age); // 学生 1 的教授不改变。
完全拷贝
在 Java 语言里深复制一个对象,常常可以先使对象实现 Serializable 接口,然后把对象(实际上只是对象的一个拷贝)
写到一个流里(腌成干菜),再从流里读出来(把干菜回鲜),便可以重建对象。
4 , Prototype 模式的结构
客户( Client )角色:
客户类提出创建对象的请求。
抽象原型( Prototype )角色:
这是一个抽象角色,通常由一个接口类或抽象类实现。此角色给出所有的具体原型
类所需的接口。在 Java 中,抽象原型角色通常实现了 Cloneable 接口。
具体原型( Concrete Prototype )角色:
被复制的对象。此角色需要实现抽象原型角色所要求的接口。
4.1 Prototype 模式实现 - 抽象原型
public abstract class AbstractSpoon implements Cloneable
{
String spoonName;
public void setSpoonName(String spoonName) {
this.spoonName = spoonName;
}
public String getSpoonName() {return this.spoonName;}
public Object clone()
{
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractSpoon is not Cloneable");
}
return object;
}
}
4.2 Prototype 模式实现 - 具体原型
public class SaladSpoon extends AbstractSpoon
{
public SaladSpoon()
{
setSpoonName("Salad Spoon");
}
}
public class SoupSpoon extends AbstractSpoon
{
public SoupSpoon()
{
setSpoonName("Soup Spoon");
}
}
4.3 Prototype 模式实现 - 客户
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
AbstractSpoon spoon1 = new SoupSpoon();
AbstractSpoon spoon2 = (AbstractSpoon) spoon1.clone();
System.out.println(spoon2.getSpoonName());
AbstractSpoon spoon3 = new SaladSpoon();
AbstractSpoon spoon4 = (AbstractSpoon) spoon3.clone();
System.out.println(spoon4.getSpoonName());
}
}
5 ,带原型管理器的原型模式
户( Client )角色:
客户端类向原型管理器提出创建对象的请求。
象原型( Prototype )角色:
这是一个抽象角色,通常由一个接口或抽象类实现。
角色给出所有的具体原型类所需的接口。在 Java 中,抽象原型角色通常实现了 Cloneable 接口
体原型( Concrete Prototype )角色:
被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
型管理器( Prototype Manager )角色:
创建具体原型类的对象,并记录每一个被创建的对象。
5.1 带原型管理器的原型模式实现 – 原型管理器
import java.util.HashMap;
public class SpoonManager {
private HashMap hm = null;
private static SpoonManager spoonManager = null;
private SpoonManager(){
hm = new HashMap();
}
public static synchronized SpoonManager getSpoonManager(){
if(spoonManager == null){
spoonManager = new SpoonManager();
}
return spoonManager;
}
public void register(String name, Object prototype){
hm.put(name,prototype);
}
public void unRegister(String name){
hm.remove(name);
}
public Object getSpoon(String name){
Object o = null;
if(hm.containsKey(name)){
o = hm.get(name);
}else{
try{// 自动查找原型管理器里不存在的类,并动态生成它
o = Class.forName(name).newInstance();
this.register(name,o);
}catch(Exception e){
System.out.println("class "+name+" don't define
"+e.getMessage());
e.printStackTrace();
}
}
return ((AbstractSpoon)o).clone();
5.2 带原型管理器的原型模式实现 – 客户
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
AbstractSpoon soupSpoon = new SoupSpoon();
AbstractSpoon saladSpoon = new SaladSpoon();
SpoonManager spoonManager = SpoonManager.getSpoonManager();
spoonManager.register("prototype.test.SoupSpoon", soupSpoon);
spoonManager.register("prototype.test.SaladSpoon", saladSpoon);
AbstractSpoon soupSpoon2 = (AbstractSpoon)
spoonManager.getSpoon("prototype.test.SoupSpoon");
AbstractSpoon saladSpoon2 = (AbstractSpoon)
spoonManager.getSpoon("prototype.test.SaladSpoon");
System.out.println(soupSpoon.hashCode());
System.out.println(soupSpoon2.hashCode());
System.out.println(saladSpoon.hashCode());
System.out.println(saladSpoon2.hashCode());
}
}
6 , Prototype 模式的优点与缺点
⑴Prototype 模式的优点:
Prototype 模式允许动态增加或减少产品类。由于创建产品类
实例的方法是产批类内部具有的,因此增加新产品对整个结构
没有影响。
Prototype 模式提供了简化的创建结构。工厂方法模式常常需
要有一个与产品类等级结构相同的等级结构,而 Prototype 模
式就不需要这样。
Portotype 模式具有给一个应用软件动态加载新功能的能力。
由于 Prototype 的独立性较高,可以很容易动态加载新功能而
不影响老系统。
产品类不需要非得有任何事先确定的等级结构,因为
Prototype 模式适用于任何的等级结构。
⑵Prototype 模式的缺点
Prototype 模式的最主要缺点就是每一个类必须配备一个克隆
方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对
全新的类来说不是很难,但对已有的类进行改造时,不一定是
件容易的事。
7, Prototype 原型模式总结
Prototype模式就是用来(通过)复制(创建)对象的。
什么时候应该使用prototype模式呢?
1, 当你要创建的对象与现有运行时对象相似度很大时
2, 为了避免创建类的工厂类导致层次复杂度增加时
3, 当类的实例只有不多的几种状态时(此时需要引进原 型管理器)
Question Time
Thanks!

Mais conteúdo relacionado

Mais procurados

[圣思园][Java SE]Reflection
[圣思园][Java SE]Reflection[圣思园][Java SE]Reflection
[圣思园][Java SE]ReflectionArBing Xie
 
《Python 3.5 技術手冊》第六章草稿
《Python 3.5 技術手冊》第六章草稿《Python 3.5 技術手冊》第六章草稿
《Python 3.5 技術手冊》第六章草稿Justin Lin
 
CH09:Collection與Map
CH09:Collection與MapCH09:Collection與Map
CH09:Collection與MapJustin Lin
 
Java程序员面试之葵花宝典
Java程序员面试之葵花宝典Java程序员面试之葵花宝典
Java程序员面试之葵花宝典yiditushe
 
Row Set初步学习V1.1
Row Set初步学习V1.1Row Set初步学习V1.1
Row Set初步学习V1.1Zianed Hou
 
Javascript之昨是今非
Javascript之昨是今非Javascript之昨是今非
Javascript之昨是今非Tony Deng
 
Java SE 7 技術手冊第六章草稿 - 何謂繼承?
Java SE 7 技術手冊第六章草稿 - 何謂繼承?Java SE 7 技術手冊第六章草稿 - 何謂繼承?
Java SE 7 技術手冊第六章草稿 - 何謂繼承?Justin Lin
 
由一个简单的程序谈起――之五(精华)
由一个简单的程序谈起――之五(精华)由一个简单的程序谈起――之五(精华)
由一个简单的程序谈起――之五(精华)yiditushe
 
CH04:認識物件
CH04:認識物件CH04:認識物件
CH04:認識物件Justin Lin
 
Python面向对象开发基础篇
Python面向对象开发基础篇Python面向对象开发基础篇
Python面向对象开发基础篇modou li
 
2011中正資管學術部講座 Java-Object
2011中正資管學術部講座 Java-Object2011中正資管學術部講座 Java-Object
2011中正資管學術部講座 Java-ObjectVeck Hsiao
 
NHibernate分享(1) share
NHibernate分享(1) shareNHibernate分享(1) share
NHibernate分享(1) shareXu Huang
 
jQuery 選取器解析
jQuery 選取器解析jQuery 選取器解析
jQuery 選取器解析Kingsley Zheng
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換Justin Lin
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题yiditushe
 
Java面试宝典
Java面试宝典Java面试宝典
Java面试宝典ma tao
 

Mais procurados (20)

[圣思园][Java SE]Reflection
[圣思园][Java SE]Reflection[圣思园][Java SE]Reflection
[圣思园][Java SE]Reflection
 
《Python 3.5 技術手冊》第六章草稿
《Python 3.5 技術手冊》第六章草稿《Python 3.5 技術手冊》第六章草稿
《Python 3.5 技術手冊》第六章草稿
 
CH09:Collection與Map
CH09:Collection與MapCH09:Collection與Map
CH09:Collection與Map
 
Java物件導向
Java物件導向Java物件導向
Java物件導向
 
Java程序员面试之葵花宝典
Java程序员面试之葵花宝典Java程序员面试之葵花宝典
Java程序员面试之葵花宝典
 
Row Set初步学习V1.1
Row Set初步学习V1.1Row Set初步学习V1.1
Row Set初步学习V1.1
 
Sun java
Sun javaSun java
Sun java
 
Javascript之昨是今非
Javascript之昨是今非Javascript之昨是今非
Javascript之昨是今非
 
認識物件
認識物件認識物件
認識物件
 
Java SE 7 技術手冊第六章草稿 - 何謂繼承?
Java SE 7 技術手冊第六章草稿 - 何謂繼承?Java SE 7 技術手冊第六章草稿 - 何謂繼承?
Java SE 7 技術手冊第六章草稿 - 何謂繼承?
 
由一个简单的程序谈起――之五(精华)
由一个简单的程序谈起――之五(精华)由一个简单的程序谈起――之五(精华)
由一个简单的程序谈起――之五(精华)
 
CH04:認識物件
CH04:認識物件CH04:認識物件
CH04:認識物件
 
Python面向对象开发基础篇
Python面向对象开发基础篇Python面向对象开发基础篇
Python面向对象开发基础篇
 
2011中正資管學術部講座 Java-Object
2011中正資管學術部講座 Java-Object2011中正資管學術部講座 Java-Object
2011中正資管學術部講座 Java-Object
 
NHibernate分享(1) share
NHibernate分享(1) shareNHibernate分享(1) share
NHibernate分享(1) share
 
jQuery 選取器解析
jQuery 選取器解析jQuery 選取器解析
jQuery 選取器解析
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题
 
Java面试宝典
Java面试宝典Java面试宝典
Java面试宝典
 
Js培训
Js培训Js培训
Js培训
 

Semelhante a 组合、备忘录、建造者模式、原型

4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构Zelin Wang
 
JVM内容管理和垃圾回收
JVM内容管理和垃圾回收JVM内容管理和垃圾回收
JVM内容管理和垃圾回收Tony Deng
 
jQuery底层架构
jQuery底层架构jQuery底层架构
jQuery底层架构fangdeng
 
Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器
Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器
Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器Justin Lin
 
從模組到類別
從模組到類別從模組到類別
從模組到類別Justin Lin
 
详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用
详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用
详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用FLASH开发者交流会
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料yiditushe
 
[圣思园][Java SE]Java se lesson 3
[圣思园][Java SE]Java se lesson 3[圣思园][Java SE]Java se lesson 3
[圣思园][Java SE]Java se lesson 3ArBing Xie
 
Java相关基础知识
Java相关基础知识Java相关基础知识
Java相关基础知识yiditushe
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训yiditushe
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术bigqiang zou
 
Java面试32题
Java面试32题Java面试32题
Java面试32题yiditushe
 
16 CoreData
16 CoreData16 CoreData
16 CoreDataTom Fan
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascriptjay li
 
Java并发核心编程
Java并发核心编程Java并发核心编程
Java并发核心编程wavefly
 
Enqueue Lock介绍.ppt
Enqueue Lock介绍.pptEnqueue Lock介绍.ppt
Enqueue Lock介绍.pptjames tong
 
Java面试题集
Java面试题集Java面试题集
Java面试题集yiditushe
 
Spring入门纲要
Spring入门纲要Spring入门纲要
Spring入门纲要yiditushe
 

Semelhante a 组合、备忘录、建造者模式、原型 (20)

4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构
 
JVM内容管理和垃圾回收
JVM内容管理和垃圾回收JVM内容管理和垃圾回收
JVM内容管理和垃圾回收
 
jQuery底层架构
jQuery底层架构jQuery底层架构
jQuery底层架构
 
Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器
Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器
Java SE 7 技術手冊投影片第 15 章 - 反射器與類別載入器
 
從模組到類別
從模組到類別從模組到類別
從模組到類別
 
详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用
详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用
详解AS3的内存管理机制,有效释放FLASH内存,减少资源占用
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料
 
[圣思园][Java SE]Java se lesson 3
[圣思园][Java SE]Java se lesson 3[圣思园][Java SE]Java se lesson 3
[圣思园][Java SE]Java se lesson 3
 
Java相关基础知识
Java相关基础知识Java相关基础知识
Java相关基础知识
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术
 
Java面试32题
Java面试32题Java面试32题
Java面试32题
 
16 CoreData
16 CoreData16 CoreData
16 CoreData
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
 
Java并发核心编程
Java并发核心编程Java并发核心编程
Java并发核心编程
 
Javascript 闭包
Javascript 闭包Javascript 闭包
Javascript 闭包
 
Hibernate教程
Hibernate教程Hibernate教程
Hibernate教程
 
Enqueue Lock介绍.ppt
Enqueue Lock介绍.pptEnqueue Lock介绍.ppt
Enqueue Lock介绍.ppt
 
Java面试题集
Java面试题集Java面试题集
Java面试题集
 
Spring入门纲要
Spring入门纲要Spring入门纲要
Spring入门纲要
 

Mais de 诸葛修车网-诸葛商城 (12)

设计模式-单例、享元、工厂与抽象工厂
设计模式-单例、享元、工厂与抽象工厂设计模式-单例、享元、工厂与抽象工厂
设计模式-单例、享元、工厂与抽象工厂
 
面向对象设计原则
面向对象设计原则面向对象设计原则
面向对象设计原则
 
单元测试(Unit Test)- Spock应用
单元测试(Unit Test)- Spock应用单元测试(Unit Test)- Spock应用
单元测试(Unit Test)- Spock应用
 
Maven技术及诸葛商城应用(1)
Maven技术及诸葛商城应用(1)Maven技术及诸葛商城应用(1)
Maven技术及诸葛商城应用(1)
 
Push-推送技术
Push-推送技术Push-推送技术
Push-推送技术
 
Sonar java -Write Clean Code,Detect Bugs
Sonar java -Write Clean Code,Detect BugsSonar java -Write Clean Code,Detect Bugs
Sonar java -Write Clean Code,Detect Bugs
 
Nginx+tomcat https 配置
Nginx+tomcat  https 配置Nginx+tomcat  https 配置
Nginx+tomcat https 配置
 
如何更好地设计测试用例-BQConf
如何更好地设计测试用例-BQConf如何更好地设计测试用例-BQConf
如何更好地设计测试用例-BQConf
 
App开发过程的演变之路
App开发过程的演变之路App开发过程的演变之路
App开发过程的演变之路
 
浅谈项目管理(诸葛B2B电商研发部版改)
浅谈项目管理(诸葛B2B电商研发部版改)浅谈项目管理(诸葛B2B电商研发部版改)
浅谈项目管理(诸葛B2B电商研发部版改)
 
Java多线程技术
Java多线程技术Java多线程技术
Java多线程技术
 
Git基础培训
Git基础培训Git基础培训
Git基础培训
 

组合、备忘录、建造者模式、原型