开放-封闭原则(OCP)

开放-封闭原则(Open-Closed Principle OCP)

参考书籍

敏捷软件开发 原则、模式与实践
Agile Software Development Principles, Patterns, and Practices

问题1:怎样的设计才能面对需求的改变却可以保持相对稳定?

如果程序中的一处改动就会产生连锁反应,导致一系列相关模块的改动,那么设计就具有僵化性的臭味。 OCP 建议我们应该对系统进行重构,这样以后对系统再进行那样的改动时,就不会导致更多的修改。如果正确地应用 OCP ,那么以后再进行同样的改动时,就只需要添加新的代码,而不必改动已经正常运行的代码。

遵循 OCP 原则设计出的模块具有两个主要的特征:
1. 对于扩展是开放的 (Open for extension)
这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。
2. 对于更改是封闭的 (Close for modification)
对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL 或者 Java 的 .jar 文件,都无需改动。

问题2:怎样可能在不改动模块源代码的情况下去更改模块的行为呢?怎样才能在无需对模块进行改动的情况下就改变模块的功能呢?

关键是抽象
模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,所以它对于更改可以是关闭的。同时,通过从这个抽象体派生,也可以扩展此模块的行为。

一个简单的不遵循 OCP 的设计


class Server
{
public:
    void doSomething()
    {
    }
}

class Client
{
public:
    void toDoSomething() 
    {
        Server s;
        s.doSomething();
    }
}


Server <– Client

Client类和Server类都是具体类。Client类使用Server类。如果我们希望Client对象使用另一个不同的服务器对象,那么就必须要把Client类中使用Server类的地方更改为新的服务器类。

遵循 OCP 的设计
方法1:strategy模式


class ClientInterface    // 抽象
{
public:
    virtual void doSomething() = 0;
}

class Client
{
public:
    void setInterface(ClientInterface *pObj)
    {
        m_pObj = pObj;
    }  

    void toDoSomething()
    {
        if(m_pObj)
        {
            m_pObj->doSomething();
        }
    }

private:
    ClientInterface *m_pObj;
}

class Server : public ClientInterface
{
public:
    virtual void doSomething()
    {
    }
}    

class ServerNew : public ClientInterface
{
public:
    virtual void doSomething()
    {
    }
}

方法2:template method模式


class Client
{
public:
    virtual void doSomething() = 0;
    void toDoSomething()
    {
        doSomething();
    }
}

class Server : public Client
{
    virtual void doSomething()
    {
    }
}

这两个模式是满足 OCP 的最常见的方法。可以把一个功能的通用部分和实现部分清晰的分离开来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值