SOLID之OCP

简介: 开闭原则 OCP Open-Closed Principle设计良好的计算机软件应该易于扩展,同时抗拒修改换句话说,一个良好的计算机系统应该在不需要修改的前提下就可以轻易被扩展遵循开闭原则设计出的模块具有两个特征:1. “对于扩展是开放的”,当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为2. “对于更改是封装的”,对模块进行扩展时,不必改动原有的代码

开闭原则 OCP Open-Closed Principle

设计良好的计算机软件应该易于扩展,同时抗拒修改

换句话说,一个良好的计算机系统应该在不需要修改的前提下就可以轻易被扩展

遵循开闭原则设计出的模块具有两个特征:

  1. “对于扩展是开放的”,当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为
  2. “对于更改是封装的”,对模块进行扩展时,不必改动原有的代码

其实这也是研究软件架构的根本目的。如果对原始需求的小小延伸就需要对原有的软件系统进行大幅修改,那么这个系统的架构设计显示是失败的

一个好的软件架构设计师会努力将旧代码的修改需求量降至最小,甚至为0

这原则看着很矛盾,需要扩展,但却又不要修改;那么如何实现这个原则呢?

抽象,面向接口编程

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

client,server都是具体类,client使用server

image.gifimage.png

如果client想使用另一个server对象,那么需要修改client中使用server的地方

显然这样违反了OCP

image.gifimage.png

在新的设计中,添加了ClientInterface接口,此接口是一个拥有抽象成员函数的抽象类。Client类使用这个抽象类。如果我们希望client对象使用不同的server,只需要从clientinterface类派生一个新类,client无需任何修改

interface ClientInterface
{
    public void Message();
    //Other functions
}
class Server:ClientInterface
{
    public void Message();
}
class Client 
{
   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();
}

OCP设计类与模块时的重要原则,但是在架构层面,这项原则意义更重大。

在设计时,可以先将满足不同需求的代码分组(SRP),然后再来调整这些分组之间的依赖关系(DIP)

IOC是不是也有OCP的味道

OCP算是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术的巨大好处(灵活性,可重用性以及可维护性)

然而,并不是说只要使用一种面向对象语言就得遵循这个原则。对于应用程序中每个部分都肆意地进行抽象同样不是一个好主意。正确的做法是,开发人员应该仅仅对程序中呈现出频繁变化的那些部分进行抽象,拒绝不成熟的抽象和抽象本身一样重要


Common Closure Principle(CCP)共同封闭原则

CCP延伸了开闭原则(OCP)的“关闭”概念,当因为某个原因需要修改时,把需要修改的范围限制在一个最小范围内的包里

一个包中所有的类应该对同一种类型的变化关闭。一个变化影响一个包,便影响了包中所有的类。一个更简短的说法是:一起修改的类,应该组合在一起(同一个包里)。如果必须修改应用程序里的代码,我们希望所有的修改都发生在一个包里(修改关闭),而不是遍布在很多包里。CCP原则就是把因为某个同样的原因而需要修改的所有类组合进一个包里。如果2个类从物理上或者从概念上联系得非常紧密,它们通常一起发生改变,那么它们应该属于同一个包。

CCP还是解决分布式单体可怕的反模式的法宝

在现流行的微服务架构中,按业务能力和子域以及SRP和CCP进行分解是将应用程序分解为服务的好方法


目录
相关文章
|
6天前
|
设计模式 前端开发 关系型数据库
SOLID设计原则和我的一点个人感悟
SOLID设计原则和我的一点个人感悟
28 0
|
7月前
|
敏捷开发 存储 关系型数据库
码农也要有原则 : SOLID via C#
让姑姑不再划拳 码农也要有原则 : SOLID via C#
39 0
 码农也要有原则 : SOLID via C#
SOLID原则之里氏替换原则
SOLID原则之里氏替换原则
|
11月前
|
消息中间件 设计模式 存储
【Java设计模式 经典设计原则】二 SOLID-OCP开闭原则
【Java设计模式 经典设计原则】二 SOLID-OCP开闭原则
72 0
|
12月前
|
存储 JavaScript 前端开发
【软件设计】TypeScript 中的 SOLID 原则
【软件设计】TypeScript 中的 SOLID 原则
|
设计模式 消息中间件 存储
软件设计 软件设计模式之SOLID原则
软件设计 软件设计模式之SOLID原则
76 0
|
JavaScript 前端开发 算法
Solid,一个前端超新星项目?
本文适合对新兴前端技术框架感兴趣的小伙伴阅读
Solid,一个前端超新星项目?
|
安全
一分钟搞懂 SOLID 原则
一分钟搞懂 SOLID 原则
157 0
一分钟搞懂 SOLID 原则
|
程序员 微服务
SOLID之SRP
单一职责原则 SRP,single responsibility principle SRP是所有原则中最简单的之一,也是最难正确运用的之一,也是我们日常中最常用的一个 不管是编码,重构,甚至当下流行的微服务中 在很多团队的规范中,都会听到一条编码规范:一个方法不要超过x行代码 作为一群自命不凡的程序员,为什么在规范中却有如此一条格调不对称规范 主要问题就在于思维对SRP的缺失
92 0
|
关系型数据库 Java 网络架构
SOLID之LSP
里氏代换原则 LSP,Liskov Substitution Principle 子类型必须能够替换掉它们的基类型 若对每个类型S的对象O1,都存在一个类型T的对象O2,使得在所有针对T编写的程序P中,用O1替换O2后,程序P行为功能不变,则S是T的子类型 LSP是继承关系设计基本原则,也是使OCP成为可能的主要原则之一。正是子类型的可替换性才使得使用基类类型的模块在无需修改的情况下就可以扩展,对于LSP的违反常常会导致以明显违反OCP的方式使用运行时类型辨别(RTTI),这种方式常常是使用一个显式的if语句或才if/else链去确定一个对象的类型
110 0