zoukankan      html  css  js  c++  java
  • 设计模式 笔记 原型模式 prototype



    //---------------------------15/04/07----------------------------


    //prototype 原型模式--对象创建型模式


    /*

        1:意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

        2:动机:

        3:适用性:

            1>当一个系统应该独立于它的产品创建、构成和表示时

            2>当要实例化的类是在运行时刻制定时,例如通过动态装载

            3>为了避免创建一个与产品类层次平行的工厂类层次时

            4>当一个类的实例只能有几个不同状态组合中的一种时

        4:结构:

            Client:

            prototype------------------------------->Prototype:

            Operation()                              Clone()

            { p = prototype->Clone()}                   |

                                                |                   |

                                    ConcretePrototype1:     ConcretePrototype2:

                                    Clone()                 Clone()

                                    {return copy of self}   {return copy of self}

        5:参与者:

            1>Prototype:声明一个克隆自身的接口。

            2>ConcretePrototype:实现一个克隆自身的操作。

            3>Client:让一个原型克隆自身从而创建一个新的对象。

        6:协作:客户请求一个原型克隆自身。

        7:效果:

            1>优点:

                1)运行时刻可以增加和删除产品,更加灵活。

                2)改变值以指定新对象。 可以为对象指定新值来实例化新的对象,

                  这种设计可以极大减少系统所需的类的数目。

                3)改变结构以制定新对象。 针对一些由部件和子部件来创建的对象,

                  反映了Composite模式(改变child的多少或类型等)以及Decorator模式(暂时不知道<未知标记>)

                  这里Clone需要实现为深拷贝,不然child都是一样的这个结构改变一下,别的结构就跟着改变了。

                4)减少子类的构造。相比较于Factory Method,不需要创建一个creator类层次,

                  需要一个对象时只用克隆一个就行,而不是靠creator类创建。

                5)用类动态配置应用(不懂<未知标记>)

            2>缺陷:

                每一个子类都必须实现Clone操作。当类已经存在,新增Clone操作会很难。当内部包括一些不

                支持拷贝(不支持拷贝,就无法调用拷贝构造函数实现Clone操作)或有循环引用(要实现深拷贝,就

                要不断重复了)的对象时,实现克隆也会很困难。

        8:实现:

            1>使用一个原型管理器。 当一个系统中原型数目不固定时(也就是,客户会动态创建和销毁),要保持一个可

              用原型的注册表。客户可以通过注册表来存储和检索原型。

            2>实现克隆操作。对一些复杂的对象进行深拷贝。

            3>初始化克隆对象 如果原型的类已经定义好了设置关键状态的操作就不用提供initialize操作,

              否则,就必须提供一个initialize操作来初始化参数。

        9:代码示例:                                                         */


    //原型工厂

    class MazePrototypeFactory : public MazeFactory

    {

    public:

        MazePrototypeFactory(Maze*, Wall*, Room*, Door*);

        

        virtual Maze* MakeMaze() const;

        virtual Room* MakeRoom(int) const;

        virtual Wall* MakeWall() const;

        virtual Door* MakeDoor(Room*, Room*) const;

        

    private:

        Maze*   _prototypeMaze;

        Room*   _prototypeRoom;

        Wall*   _prototypeWall;

        Door*   _prototypeDoor;

    };


    //初始化每一个原型

    MazePrototypeFactory::MazePrototypeFactory

    (Maze* m, Wall* w, Room* r, Door* d)

    {

        _prototypeMaze = m;

        _prototypeRoom = r;

        _prototypeWall = w;

        _prototypeDoor = d;

    }


    //实现基类的virtual方法,内部调用Clone实现

    Wall* MazePrototypeFactory::MakeWall() const

    {

        return _prototypeWall->Clone();

    }


    //效用Clone后还要初始化克隆对象

    Door* MazePrototypeFactory::MakeDoor(Room* r1, Room* r2) const

    {

        Door* door = _prototypeDoor->Clone();

        door->Initialize(r1, r2);

        return door;

    }

    //使用方法

    MakeGame game;

    MazePrototypeFactory simpleMazeFactor(new Maze, new Wall, new Room, new Door);

    maze* maze = game.CreateMaze(simpleMazeFactor);

    /////////


    //下面要换其中的部件,来实现新的原型类,要作为部件,必须实现clone操作

    MazePrototypeFactory bombedMazeFactory(

    new Maze, new BombedWall, new RoomWithABomb, new Door);


    //Door中有两个数据可以设置或者说需要设置,所以要提供一个initilize函数

    class Door : public MapSite

    {

    public:

        Door();

        Door(const Door&);

        

        virtual void Initialize(Room*, Room*);

        virtual Door* Clone() const;

        virtual void Enter();

        Room* OtherSideFrom(Room*);

        

    private:

        Room* _room1;

        Room* _room2;

    };


    Door::Door (const Door& other)

    {

        _room1 = other._room1;

        _room2 = other._room2;

    }


    void Door::Initialize(Room* r1, Room* r2)

    {

        _room1 = r1;

        _room2 = r2;

    }


    Door* Door::Clone() const

    {

        return new Door(*this);

    }


    //这里应该也有一个initialize函数才对。用来设置是否有炸弹

    class BombedWall : public wall

    {

    public:

        BombedWall();

        BombedWall(const BombedWall&);

        

        virtual Wall* Clone() const;

        bool HasBomb();

        

    private:

        bool _bomb;

    };


    BombedWall::BombedWall(const BombedWall& other) : Wall(other)

    {

        _bomb = other._bomb;

    }


    Wall* BombedWall::Clone() const

    {

        return new BombedWall(*this);

    }


    //这样子每次用的时候都要重新使用部件创建一个

    //可以用一个map存起来

    map<string,MazePrototypeFactory> MazeTable;

    MazeTable.insert(make_pair("bombedMazeFactory",bombedMazeFactory));

    //要用的时候取出:

    game.CreateMaze(map["bombedMazeFactory"]);

    //可以把直接map封装到game中,然后致用传入一个字符串就行。

    //不过这样需要提供一个注册函数和销毁函数,来对进行注册和销毁。


    //下面是ios设计模式解析版本的:

    /*

        1:在以下情形,会考虑使用原型模式:

            1>需要创建的对象应独立于其类型与创建方式。(太抽象<未知标记>)

            2>要实例化的类是在运行时决定的。

            3>不想要与产品层次相对应的工厂层次。

            4>不同类的实例间的差异仅仅是状态的若干组合。因此复制响应数量的原型比手工实例化更加方便。

            5>类不容易创建,比如每个组件可以把其他组件作为子节点的组合对象。复制已有的组合

              对象,并对副本进行修改会更加容易。

        2:考虑使用原型模式的情景:

            1>有很多相关的类,其行为略不同,而且主要差别在于内部属性,比如名称,图像等;

            2>徐傲使用组合对象作为其他东西的基础,比如,使用组合对象作为组件来构建另一个组合对象。

    */




  • 相关阅读:
    032 Gradle 下载的依赖jar包在哪?
    031 can't rename root module,Android Studio修改项目名称
    030 Cannot resolve symbol'R' 问题解决汇总大全
    029 Android Studio层级显示目录文件
    028 You are about to commit CRLF line separators to the Git repository.It is recommended to set the core. autocrlf Git attribute to true to avoid line separator issues If you choose Fix and Comit ,
    027 【Android基础知识】Android Studio 编译慢及 Adb connection Error:远程主机强迫关闭了一个现有的连接
    026 Android Studio 和Gradle版版本对应关系
    025 Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm
    024 Android Studio上传项目到Github 最全记录
    023 解决AndroidStudio下载gradle慢的问题
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983145.html
Copyright © 2011-2022 走看看