【23种设计模式】原型模式(五)

设计模式,原型,模式 · 浏览次数 : 124

小编点评

**原型模式** **定义** 原型模式是一种创建对象的方式,它允许通过对原型类的复制来创建新的对象。原型模式的组成原型类(Prototype)定义了原型本身所具有的特征和动作,该类型就是至尊宝。具体原型创建两个具体原型:行者孙和孙行者行者孙。 **优点** * 将创建对象的复杂性隐藏在原型中。 * 允许动态增加或较少产品类。 * 简化实例的创建结构。 **缺点** * 每类必须配备一个克隆方法。 * 配置原型类需要对类的功能进行通盘考虑。 * 对于全新的类可能难以实现克隆方法。

正文

前言

在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这就会增加创建类的复杂度和创建过程与客户代码复杂的耦合度。如果采用工厂模式来创建这样的实例对象的话,随着产品类的不断增加,导致子类的数量不断增多,也导致了相应工厂类的增加,维护的代码维度增加了,因为有产品和工厂两个维度了,反而增加了系统复杂程度,所以在这里使用工厂模式来封装类创建过程并不合适。由于每个类实例都是相同的,这个相同指的是类型相同,但是每个实例的状态参数会有不同,如果状态数值也相同就没意义了,有一个这样的对象就可以了。当我们需要多个相同的类实例时,可以通过对原来对象拷贝一份来完成创建,这个思路正是原型模式的实现方式。

原型模式的定义

在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。如何应对这种变化?如何向“客户程序”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?那就是原型模式,使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。

原型模式的组成

image

  • 原型类(Prototype):原型类,声明一个Clone自身的接口;

  • 具体原型类(ConcretePrototype):实现一个Clone自身的操作。

在原型模式中,Prototype通常提供一个包含Clone方法的接口,具体的原型ConcretePrototype使用Clone方法完成对象的创建。

原型模式的实现

《大话西游之大圣娶亲》这部电影,没看过的人不多吧,里面有这样一个场景。牛魔王使用无敌牛虱大战至尊宝,至尊宝的应对之策就是,从脑后把下一撮猴毛,吹了口仙气,无数猴子猴孙现身,来大战牛魔王的无敌牛虱。至尊宝的猴子猴孙就是该原型模式的最好体现。至尊宝创建自己的一个副本,不用还要重新孕育五百年,然后出世,再学艺,最后来和老牛大战,估计黄花菜都凉了。他有3根救命猴毛,轻轻一吹,想要多少个自己就有多少个,方便,快捷。

抽象原型
 /// <summary>
    /// 抽象原型,定义了原型本身所具有特征和动作,该类型就是至尊宝
    /// </summary>
    public abstract class Prototype
    {
        /// <summary>
        /// 战斗--保护师傅
        /// </summary>
        public abstract void Fight();
        /// <summary>
        /// 化缘--不要饿着师傅
        /// </summary>
        public abstract void BegAlms();

        /// <summary>
        /// 吹口仙气--变化一个自己出来
        /// </summary>
        /// <returns></returns>
        public abstract Prototype Clone();
    }
具体原型

创建两个具体原型:行者孙和孙行者

行者孙:

 /// <summary>
    /// 具体原型,例如:行者孙,他只负责化斋饭食和与天界宠物下界的妖怪的战斗
    /// </summary>
    public sealed class XingZheSunPrototype : Prototype
    {
        /// <summary>
        /// 战斗--保护师傅--与自然修炼成妖的战斗
        /// </summary>
        public override void Fight()
        {
            Console.WriteLine("行者孙:腾云驾雾,与天界宠物下界的妖怪的战斗....");
        }
        /// <summary>
        /// 化缘--不要饿着师傅--饭食类
        /// </summary>
        public override void BegAlms()
        {
            Console.WriteLine("行者孙:化缘鸡鱼肉蛋....");
        }

        /// <summary>
        /// 吹口仙气--变化一个自己出来
        /// </summary>
        /// <returns></returns>
        public override Prototype Clone()
        {
            return (XingZheSunPrototype)this.MemberwiseClone();
        }
    }

孙行者:

  /// <summary>
    /// 具体原型,例如:孙行者,他只负责与自然界修炼成妖的战斗和化斋水果
    /// </summary>
    public sealed class SunXingZhePrototype : Prototype
    {
        /// <summary>
        /// 战斗--保护师傅-与天界宠物战斗
        /// </summary>
        public override void Fight()
        {
            Console.WriteLine("孙行者:腾云驾雾,与自然界修炼成妖的战斗....");
        }
        /// <summary>
        /// 化缘--不要饿着师傅---水果类
        /// </summary>
        public override void BegAlms()
        {
            Console.WriteLine("孙行者:化缘水果....");
        }

        /// <summary>
        /// 吹口仙气--变化一个自己出来
        /// </summary>
        /// <returns></returns>
        public override Prototype Clone()
        {
            return (SunXingZhePrototype)this.MemberwiseClone();
        }
    }
调用
public void RunTest()
        {
            //原型行者孙
            Prototype xingZheSun = new XingZheSunPrototype();
            Prototype xingZheSun2 = xingZheSun.Clone();
            Prototype xingZheSun3 = xingZheSun.Clone();
            //1号行者孙打妖怪
            xingZheSun.Fight();
            //2号行者孙去化缘
            xingZheSun3.BegAlms();
            Console.WriteLine("\r\n*****************************\r\n");
            //原型孙行者
            Prototype sunXingZhe = new SunXingZhePrototype();
            Prototype sunXingZhe2 = sunXingZhe.Clone();
            Prototype sunXingZhe3 = sunXingZhe.Clone();
            Prototype sunXingZhe4 = sunXingZhe.Clone();
            Prototype sunXingZhe5 = sunXingZhe.Clone();

            //1号孙行者打妖怪
            sunXingZhe.Fight();
            //2号孙行者去化缘
            sunXingZhe2.BegAlms();

            //战斗和化缘也可以分类,比如化缘,可以分:水果类化缘,饭食类化缘;战斗可以分为:天界宠物下界成妖的战斗,自然修炼成妖的战斗,大家可以自己去想吧,原型模式还是很有用的

        }

image

原型模式的优缺点

优点
  • 原型模式向客户隐藏了创建新实例的复杂性。

  • 原型模式允许动态增加或较少产品类。

  • 原型模式简化了实例的创建结构,工厂方法模式需要有一个与产品类等级结构相同的等级结构,而原型模式不需要这样。

  • 产品类不需要事先确定产品的等级结构,因为原型模式适用于任何的等级结构。

缺点
  • 每个类必须配备一个克隆方法。

  • 配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。

与【23种设计模式】原型模式(五)相似的内容:

【23种设计模式】原型模式(五)

## 前言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这就会增加创建类的复杂度和创建过程与客户代码复杂的耦合度。如果采用工厂模式来创建这样的实例对象的话,随着产品类的不断增加,导致子类的数量不断增多,也导致了相

【23种设计模式】设计模式综述(开篇)

## 一、设计模式概述: ​ **设计模式(Design pattern)**代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。是一套被反复使用的、多

【23种设计模式】单例模式(一)

## 前言: 单例模式是创建型模式5种中的第1种,**关注对象的创建, 保证一个类仅有一个实例,并且提供一个全局访问点**。在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。如何绕过常规的构造器,提供一种机制来保证一个类只创建一个实例

【23种设计模式】工厂方法模式(二)

## 前言 在讲述之工厂方法模式前,我们来先了解简单工厂模式,简单工厂模式是最简单的设计模式之一,它虽然不属于GoF的23种设计模式,但是应用也较为频繁,同时它也是学习其他创建型模式的基础。下面我们来先了解下简单工厂模式,然后针对它的缺点来引出工厂方法模式。 ## 简单工厂模式定义 **简单工厂模式

【23种设计模式】抽象工厂模式(三)

## 前言 在抽象工厂模式开篇之前,我们先思考一个问题,如果我们要设计一套房子,其他的组件暂时不考虑,我们仅仅考虑房顶、地板、窗户、房门进行设计。什么样的风格暂时未知,可能会有很多种类。可以先设计一套古典风格的房子,再设计一套现代风格的房子,再设计一套欧式风格的房子....这么多套房子需要设计,需求

【23种设计模式】建造者模式(四)

## 前言 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中

【23种设计模式】适配器模式(六)

## 前言 从今天开始我们开始讲【结构型】设计模式,【结构型】设计模式有如下几种:**适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式**。【创建型】的设计模式解决的是对象创建的问题,那【结构型】设计模式解决的是类和对象的组合关系的问题。 今天我们就开始讲【结构型】设计模式里面

【23种设计模式】桥接模式(七)

## 前言 【**桥接模式**】是【**结构型**】设计模式的第二个模式,也有叫【桥模式】的,英文名称:**Bridge Pattern**。 大家第一次看到这个名称会想到什么呢?我第一次看到这个模式根据名称猜肯定是连接什么东西的。因为桥在我们现实生活中经常是连接着A地和B地,再往后来发展,桥引申为

【23种设计模式】组合模式(八)

前言 组合模式,英文名称是:Composite Pattern。当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意思,那就是“俄罗斯套娃”。“俄罗斯套娃”就是大的瓷器娃娃里面装着一个小的瓷器娃娃,小的瓷器娃娃里面再装着更小的瓷器娃娃,直到最后一个不能再装更小的瓷器娃娃的那个

【23种设计模式】装饰模式(九)

前言 装饰模式,英文名称:Decorator Pattern。我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理解吧,大家一定要看清楚,是“装修”,不是“装饰”。在房子装修的过程中,各种功能可以相互组合,来增加房子的功用。类似的,如果我们在软件系统中,要给某个类型或者对象增加