设为首页 收藏本站
查看: 2568|回复: 0

[经验分享] <总结> 设计模式之 开放封闭原则OCP C++示例

[复制链接]

尚未签到

发表于 2015-6-16 12:33:42 | 显示全部楼层 |阅读模式
  原文是C++ VIEW第二期的一篇译文,这里做个总结,便于查阅。  
  开放封闭原则
  系统在添加新的需求的时候能够尽可能做到,只是添加新的代码 open for extension,而不需要修改原有模块代码 closed for modification DSC0000.png
  
DSC0001.png
  通过提取基类的方法,client 调用server 抽象基类abstract server的抽象接口,从而更换不同sever的时候,client的调用server的代码都不需要改动,接口不变,
  只是server内容变化。
  

  例子,
  一个绘制函数,要求能够针对输入的不同对象,调用不同的绘制函数,如能够绘制矩形,圆形,适当调用矩形绘制函数,圆形绘制函数。
  1.用c语言实现
  这个例子其实给出了,c语言模拟c++类继承的方法。利用指针的强制转换,因为指针仅仅是地址可以指向任何对象,利用指针强制转换,告诉编译器具体按什么对象处理指针所指。
  Listing 1
/*Procedural Solution to the Square/Circle Problem*/
  enum ShapeType {circle, square};
struct Shape
{
    ShapeType itsType;
};
struct Circle
{
    ShapeType itsType;
    double itsRadius;
    Point itsCenter;
};
struct Square
{
    ShapeType itsType;
    double itsSide;
    Point itsTopLeft;
};
//
// 下面两个函数的实现定义在别处
//
void DrawSquare(struct Square*)
void DrawCircle(struct Circle*);
typedef struct Shape *ShapePointer;
void DrawAllShapes(ShapePointer list[], int n)
{
    int i;
    for (i=0; iitsType)
        {
          case square:
              DrawSquare((struct Square*)s);
              break;
         case circle:
             DrawCircle((struct Circle*)s);
             break;
        }
     }
}
  
  上面的代码不符合open close法则,因为新加入其它的shape如椭圆, DrawAllShapes函数就需要变化。
  2. C++的实现
  Listing 2
/*OOD solution to Square/Circle problem.*/
class Shape
{
    public:
        virtual void Draw() const = 0;
};
class Square : public Shape
{
    public:
        virtual void Draw() const;
};
class Circle : public Shape
{
    public:
        virtual void Draw() const;
};
void DrawAllShapes(Set& list)
{
    for (Iteratori(list); i; i++)
        (*i)->Draw();
}   
  
  
  
  和上面C语言实现代码对比,显然符合open close 法则,加入新的shape, DrawAllShapes函数可保持不变,只是添加新的shape内容。
  
  但是事实上如果有新的需求变化,DrawAllShapes也无法做到完全不变,任何模块只能是相对封闭,无法完全封闭
  例如我们有新的需求,要求绘制图形列表的时候,一种形状的图形要在另一种图形前面绘制
  解决方法,加入 顺序抽象类

  Listing 3
/*Shape with ordering methods.*/
class Shape
{
    public:
        virtual void Draw() const = 0;
  virtual bool Precedes(const Shape&) const = 0;
        bool operatorDraw();
}
  Listing 5
/*Ordering a Circle*/
bool Circle::Precedes(const Shape& s) const
{
    if (dynamic_cast(s))
        return true;
    else
        return false;
}
  
  这里使用的Precedes函数,如果新加入shape需要改变,怎么样才能做到更好呢?
  使用数据驱动获得封闭性,利用预先写好的table,我们将各个图形的优先顺序写入table,那么新加入shape只需要更新table加入新的shape。
  Listing 6
/*Table driven type ordering mechanism*/
#include
#include
enum {false, true};
typedef int bool;
class Shape
{
public:
    virtual void Draw() const = 0;
    virtual bool Precedes(const Shape&) const;
    bool operator 0) && (thisOrd > 0))
                done = true;
        }
        else // table entry == 0
            done = true;
    }
    return thisOrd < argOrd;
}
  
  进一步扩展封闭性
故事还没有结束。我们已经设法使得Shape类层次和DrawShapes函数对于依赖于图形类型的画出顺序是封闭的。然而,如果画出顺序与图形类型无关,那么Shape派生类并不对这种顺序的变化封闭。我们似乎需要根据一个更加高层次的结构来决定画出各个shape的顺序。关于这个问题的深入彻底探讨已经超过了本文的范围;然而有兴趣的读者可能会考虑定义一个OrderedObject的抽象类,并从Shape类和OrderedObject类派生一个新的抽象类OrderedShape。
  
  所有成员变量都应该是私有的
  永远不要用全局变量
  然而,有些情况下全局变量的方便性是很重要的。全局变量cout和cin就是例子。在这种情况下,如果没有破环开放―封闭(open-closed)原则,那么牺牲风格来获得这种方便性是值得的
  RTTI是危险的
  根据一般的经验,如果使用RTTI不会破坏开放―封闭(open-closed)原则,那么就是安全的

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-77951-1-1.html 上篇帖子: OCP-1Z0-051-题目解析-第2题 下篇帖子: 闪回flashback#ocp试验#
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表