您的位置:首页 > 其它

开放-封闭原则(OCP)

2016-04-08 09:12 225 查看

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

参考书籍

敏捷软件开发 原则、模式与实践

Agile Software Development Principles, Patterns, and Practices

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

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

遵循 OCP 原则设计出的模块具有两个主要的特征:

1. 对于扩展是开放的 (Open for extension)

这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。

2. 对于更改是封
4000
闭的 (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 的最常见的方法。可以把一个功能的通用部分和实现部分清晰的分离开来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息