开放-封闭的原则
来源:互联网 发布:linux 挂起命令 编辑:程序博客网 时间:2024/04/27 23:22
一、OCP简介(OCP--Open-Closed Principle):
Software entities(classes,modules,functions,etc.) should be open for extension, but closed for modification。
软件实体应当对扩展开放,对修改关闭,即软件实体应当在不修改(在.Net当中可能通过代理模式来达到这个目的)的前提下扩展。
Open for extension:当新需求出现的时候,可以通过扩展现有模型达到目的。
Close for modification:对已有的二进制代码,如dll,jar等,则不允许做任何修改。
二、OCP举例:
1、例子一
下面这个例子就是既不开放也不封闭的,因为Client和Server都是具体类,如果我要Client使用不同的一个Server类那就要修改Client类中所有使用Server类的地方为新的Server类。 ------------------------------------------------------------------------------------------------------
class Client
{
Server server;
void GetMessage()
{
server.Message();
}
}
{
Server server;
void GetMessage()
{
server.Message();
}
}
class Server
{
void Message();
}
{
void Message();
}
------------------------------------------------------------------------------------------------------
下面为修改后符合OCP原则的实现,我们看到Server类是从ClientInterface继承的,不过ClientInterface却不叫ServerInterface,原因是我们希望对Client来说ClientInterface是固定下来的,变化的只是Server。这实际上就变成了一种策略模式(Gof Strategy)
------------------------------------------------------------------------------------------------------
interface ClientInterface
{
public void Message();
//Other functions
}
{
public void Message();
//Other functions
}
class Server:ClientInterface
{
public void Message();
}
{
public void Message();
}
class Client
{
ClientInterface ci;
public void GetMessage()
{
ci.Message();
}
public void Client(ClientInterface paramCi)
{
ci=paramCi;
}
}
{
ClientInterface ci;
public void GetMessage()
{
ci.Message();
}
public void Client(ClientInterface paramCi)
{
ci=paramCi;
}
}
//那么在主函数(或主控端)则
public static void Main()
{
ClientInterface ci = new Server();
//在上面如果有新的Server类只要替换Server()就行了.
Client client = new Client(ci);
client.GetMessage();
}
public static void Main()
{
ClientInterface ci = new Server();
//在上面如果有新的Server类只要替换Server()就行了.
Client client = new Client(ci);
client.GetMessage();
}
------------------------------------------------------------------------------------------------------
3、例子三
使用Template Method实现OCP
------------------------------------------------------------------------------------------------------
public abstract class Policy
{
private int[] i ={ 1, 1234, 1234, 1234, 132 };
public bool Sort()
{
SortImp();
}
protected virtual bool SortImp()
{
{
private int[] i ={ 1, 1234, 1234, 1234, 132 };
public bool Sort()
{
SortImp();
}
protected virtual bool SortImp()
{
}
}
}
class Bubbleimp : Policy
{
protected override bool SortImp()
{
//冒泡排序
}
}
class Bintreeimp : Policy
{
protected override bool SortImp()
{
//二分法排序
}
}
{
protected override bool SortImp()
{
//冒泡排序
}
}
class Bintreeimp : Policy
{
protected override bool SortImp()
{
//二分法排序
}
}
//主函数中实现
static void Main(string[] args)
{
//如果要使用冒泡排序,只要把下面的Bintreeimp改为Bubbleimp
Policy sort = new Bintreeimp();
sort.Sort();
}
{
//如果要使用冒泡排序,只要把下面的Bintreeimp改为Bubbleimp
Policy sort = new Bintreeimp();
sort.Sort();
}
------------------------------------------------------------------------------------------------------
三、OCP优点:
1、降低程序各部分之间的耦合性,使程序模块互换成为可能;
2、使软件各部分便于单元测试,通过编制与接口一致的模拟类(Mock),可以很容易地实现软件各部分的单元测试;
3、利于实现软件的模块的呼唤,软件升级时可以只部署发生变化的部分,而不会影响其它部分;
2、使软件各部分便于单元测试,通过编制与接口一致的模拟类(Mock),可以很容易地实现软件各部分的单元测试;
3、利于实现软件的模块的呼唤,软件升级时可以只部署发生变化的部分,而不会影响其它部分;
四、使用OCP注意点:
1、实现OCP原则的关键是抽象;
2、两种安全的实现开闭原则的设计模式是:Strategy pattern(策略模式),Template Methord(模版方法模式);
3、依据开闭原则,我们尽量不要修改类,只扩展类,但在有些情况下会出现一些比较怪异的状况,这时可以采用几个类进行组合来完成;
4、将可能发生变化的部分封装成一个对象,如: 状态, 消息,,算法,数据结构等等 , 封装变化是实现"开闭原则"的一个重要手段,如经常发生变化的状态值,如温度,气压,颜色,积分,排名等等,可以将这些作为独立的属性,如果参数之间有关系,有必要进行抽象。对于行为,如果是基本不变的,则可以直接作为对象的方法,否则考虑抽象或者封装这些行为;
5、在许多方面,OCP是面向对象设计的核心所在。遵循这个原则可带来面向对象技术所声称的巨大好处(灵活性、可重用性以及可维护性)。然而,对于应用程序的每个部分都肆意地进行抽象并不是一个好主意。应该仅仅对程序中呈现出频繁变化的那部分作出抽象。拒绝不成熟的抽象和抽象本身一样重要;
- 开放-封闭的原则
- “开放-封闭”原则--OOD的基石
- 浅谈Java的开放封闭原则
- 开放-封闭原则(OCP)
- 开放封闭原则--OCP
- OCP开放-封闭原则
- 开放封闭原则--OCP
- 开放封闭原则--OCP
- 开放-封闭原则
- 开放-封闭原则
- 开放-封闭原则
- 开放-封闭原则
- 开放封闭原则--OCP
- 开放-封闭原则
- 开放封闭原则--OCP
- 2.3 开放封闭原则
- 开放—封闭原则
- 开放封闭原则
- 使用 TreeView IE Web 控件
- 初用Blog
- 这七句话被中国人误传了数千年
- C#优化字符串操作
- asp.net利用RAR实现文件压缩解压缩
- 开放-封闭的原则
- Spring, the Resurrection Time
- 管理寓言----蜘蛛修网
- .NET中赋植的问题
- 马桶堵塞所想到的
- could not initialize proxy - the owning Session was closed
- Asp.net源码本周更新(6.11-6.15)
- Java 30个目标
- 关于PHP中出现乱码和Sessions验证问题的解决方法!