• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

JavaScript设计模式系列之原型模式_js

javascript 搞代码 7年前 (2018-06-13) 171次浏览 已收录 0个评论

prototype模式通过实例对象指定需要创建的类型,这与factory method模式有本质不同,factory method模式是通过类的继承定义不同子类来达到创建不同类型对象的目的,属于类模式,prototype模式通过调用组合的对象成员生成不同类型的对象实例,属于对象模式。

由于这个特性,prototype具有以下适用场合:

· 需要运行时确定实例化的类时,比如动态装载库时

· 避免创建过多子类时。子类太多永远是不受欢迎的,在factory method中我们也提到通过模板或者参数化来减少子类数目。

· 实例化对象的状态组合过多时,先建立原型库,使用时通过注册表取得相应原型来生成目标对象会更加方便。

prototype的优点包括:

http://www.gaodaima.com/30533.html

· 运行时增加和删除产品

· 改变对象,这点是组合模式的共同优点

· 减少子类的数目

· 用类动态配置应用

prototype的最大缺点应该就是在某些语言中实现clone操作可能会很困难,特别是包含循环引用的额情况下。

下面继续使用上一篇文章中的例子,开发一个芯片设计软件,用prototype实现。所有的图形继承自MaskFigure,必须实现clone函 数,MaskDesigner初始化时传入对象原型指针,MakeFigure时通过原型的clone生成新的图形。Factory method是通过图形对应的类调用图形类的构造函数生成新的对象,通俗点讲,就好像factory method是用设计图纸重新画了个图形出来,而prototype是临摹已经画好了的图形。类结构如下:

 JavaScript设计模式系列之原型模式_js

代码实现如下:

 //mask.hpp #ifndef MASK_HPP #define MASK_HPP  class MaskFigure{   public:     virtual ~MaskFigure()=0;     virtual MaskFigure* clone()=0;   protected:     MaskFigure();     MaskFigure(const MaskFigure&); };  class MaskRound:public MaskFigure {   public:     MaskRound();     MaskRound(const MaskRound&);     MaskRound* clone();     ~MaskRound(); };  class MaskRec:public MaskFigure {   public:     MaskRec();     MaskRec(const MaskRec&);     MaskRec* clone();     ~MaskRec(); };  class MaskTri:public MaskFigure {   public:     MaskTri();     MaskTri(const MaskTri&);     MaskTri* clone();     ~MaskTri(); }; #endif //mask.cpp #include <iostream> #include "mask.hpp"  using std::cout; using std::endl;  MaskFigure::MaskFigure() {   cout<<"init MaskFigure"<<endl; }  MaskFigure::MaskFigure(const MaskFigure& mf) {   cout<<"copy Figure"<<endl; }  MaskFigure::~MaskFigure() {   cout<<"delete MaskFigure"<<endl; }  MaskRound::MaskRound() {   cout<<"Draw roundness on Mask"<<endl; }  MaskRound::MaskRound(const MaskRound& mr) :MaskFigure(mr){   cout<<"copy roundness"<<endl; }  MaskRound* MaskRound::clone() {   return new MaskRound(*this); }  MaskRound::~MaskRound() {   cout<<"delete MaskRound"<<endl; }  MaskRec::MaskRec() {   cout<<"Draw rectangle on Mask"<<endl; }  MaskRec::MaskRec(const MaskRec& mr) :MaskFigure(mr){   cout<<"copy rectangle"<<endl; }  MaskRec* MaskRec::clone() {   return new MaskRec(*this); }  MaskRec::~MaskRec() {   cout<<"delete MaskRec"<<endl; }  MaskTri::MaskTri() {   cout<<"Draw triangle on Mask"<<endl; }  MaskTri::MaskTri(const MaskTri& mt) :MaskFigure(mt){   cout<<"copy triangle"<<endl; }  MaskTri* MaskTri::clone() {   return new MaskTri(*this); }  MaskTri::~MaskTri() {   cout<<"delete MaskTri"<<endl; }  //maskdesigner.hpp #ifndef FIGUREDESIGNER_HPP #define FIGUREDESIGNER_HPP  #include "mask.hpp"  class FigureDesigner{  public:   FigureDesigner(MaskFigure *mf){     figure = mf;   }    MaskFigure* MakeFigure(){     return figure->clone();   }   private:   MaskFigure *figure; }; #endif  //main.cc #include <memory> #include <iostream> #include "maskdesigner.hpp"  using std::cout; using std::endl; using std::shared_ptr;  int main() {   MaskRound   mro;   MaskRec     mre;   MaskTri     mtr;   FigureDesigner  md1(&mro);   shared_ptr<MaskFigure> mfptr1(md1.MakeFigure());   FigureDesigner  md2(&mre);   shared_ptr<MaskFigure> mfptr2(md2.MakeFigure());   FigureDesigner  md3(&mtr);   shared_ptr<MaskFigure> mfptr3(md3.MakeFigure()); }

讲到prototype模式,有必要提一下c++ Covariance特性,即c++的协变性质,在虚函数实现时,一般要求派生类重写的虚函数必须与基类函数有一致的返回值类型,参数个数及类型。

不过这也有个特例,如果返回值类型满足下面条件时可以不同,

1. 基类和派生类虚函数返回值类型都是指向类的指针或者引用

2. 基类虚函数返回值指针或引用所指向的类类型是派生类返回值指针或引用所指向的类类型的间接或直接基类,即属于同一个继承体系。

这表示如下情况是允许的,

 class Base { /* ... */ }; class Derived: public Base { /* ... */ };  class B {   virtual Base* func() { return new Base; }   virtual ~B() { } }; class D: public B {   Derived* func() { return new Derived; } virtual ~D() { } };

fanc的返回值分别是base*和Derived*,属于同一继承体系内。但返回值换成其他类型如基本类型时则不允许。这一特性在 prototype中得到充分的应用, MaskFigure的clone函数返回 MaskFigure*指针类型,MaskRound,MaskRec和MaskTri的clone函数分别返回MaskRound*,MaskRec* 和MaskTri*指针类型。

欢迎大家阅读javaScript设计模式系列之原型模式_js》,跪求各位点评,若觉得好的话请收藏本文,by 搞代码


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:JavaScript设计模式系列之原型模式_js

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址