定义:软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。对于扩展是开放的,对于更改是封闭的。关键是抽象,将一个功能的通用部分和实现细节部分清晰的分离开来。
这里要求我们写代码要有抽象的概念。什么是抽象?指由实体抽离出概念的思考过程。就是从众多的对象中抽离出共同的本质的特征。在写代码的过程中,需要抽象类的地方,只需要抓住这个类的本质功能,不要老想着它在这个工程中的具体功能。
我们继续看开放封闭原则,这个原则要求,将一个功能的共用部分和实现部分清晰地分离开来。因为在最初搭建架构的时候你不能预测到所有将要发生的变化,那么这个类也就不是一尘不变的,随着在各个模块中具体实现的时候,你发现抽象的类适合这个功能,但是对另一个功能又不适合。那么是否要返回去修改抽象类呢?这个代价是很大的,需要重新全盘思考,还要调整具体细节。如果程序还没发布还好一些,一旦程序发布了,那么返回修改抽象类,影响将更大。所以在开始抽象的时候就要防止这样的现象发生,要遵循开放封闭原则。抽象类、接口是一种标准,在程序中一旦定义好,就不能轻易去修改,需求有变化,怎么办呢?可以扩展这个接口,重写方法,或者继承后增加新的方法,但是一定不要去修改。
下面用两个例子来说明开放封闭原则。
1、连接数据库为例。
比如在程序中用到的不同类型的数据库连接,Access和Oracle。直接连接如下:
class ConnectAccess { public string ConnectString() { string dataPath = "数据库路径"; return string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Persist Security Info=True;Jet OLEDB:Database Password={1}", dataPath, "密码"); } } class ConnectOracle { public string ConnectString() { return @"server=localhost;database=命名空间;uid=用户名;pwd=密码"; } }
调用
static void Main(string[] args) { //连接Access ConnectAccess connAccess = new ConnectAccess(); OleDbConnection accessConnection = new OleDbConnection(connAccessConnectString()); //连接Oracle ConnectOracle connOracle = new ConnectOracle(); OracleConnection oracleConnection = new OracleConnection(connOracleConnectString()); }
这样每次都要去考虑OleDbConnection的参数到底用哪个。下面修改一下。抽象一个接口。
interface ConnectDataBase { string ConnectString(); } class ConnectAccess : ConnectDataBase { #region ConnectDataBase 成员 public string ConnectString() { string dataPath = "数据库路径"; return stringFormat("Provider=MicrosoftJetOLEDB0;Data Source={0};Persist Security Info=True;Jet OLEDB:Database Password={1}", dataPath, "密码"); } #endregion } class ConnectOracle : ConnectDataBase { #region ConnectDataBase 成员 public string ConnectString() { return @"server=localhost;database=命名空间;uid=用户名;pwd=密码"; } #endregion }
调用
static void Main(string[] args) { ConnectDataBase conn = null; //连接Access conn = new ConnectAccess(); OleDbConnection accessConnection = new OleDbConnection(connConnectString()); //连接Oracle conn = new ConnectOracle(); OracleConnection oracleConnection = new OracleConnection(connConnectString()); }
改过后,只需关心conn用哪一个类实例化,就可以了。不过大家可能看到,由于Oracle的连接必须OracleConnection,可能优势不容易看出来。
2、基本类型作为方法参数为例。
一般的设计原则之所以强调方法参数尽量避免基本类型,原因正在于此。比较如下两个方法定义:
//定义1 bool Connect(string userName, string password, string wifiAddress, int port) { return false; }
//定义2 bool Connect(Account account) { return false; }
public class Account { public string UserName { get; set; } public string Password { get; set; } public string WifiAddress { get; set; } public int Port { get; set; } }
相比较而言,定义2多了一个Account类的定义,Connect()方法明显更加稳定。如果Connect()方法wifiAddress发生改变,定义1必须修改该方法的接口,对应的,所有调用Connect()方法的对象都会受到影响;而定义2只需要修改Account类,由于Connect()方法的接口保持不变,而对于Connect()方法的调用者并不需wifiAddress,这样的修改就完全不会影响调用者,从而降低需求变化带来的影响。
总之开放封闭原则最关键的是抽象,但是也并不是说一旦抽象接口、类确定就一定不能修改。只是,我们在抽象的时候就要全面思考,争取做到不用修改,一旦需求有变化,只需在实现的时候有变动。当然,需求是千变万化的,一旦需要改动抽象的部分,那么只要前面严格遵循了该原则,影响也会小得多。当然了如果修改了,一定要进行单元测试,凡是用到的地方都要测试正确。
以上是Java中开放封闭原则的详解的详细内容。更多信息请关注PHP中文网其他相关文章!

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

封装是一种信息隐藏技术,是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法;封装可以被认为是一个保护屏障,防止指定类的代码和数据被外部类定义的代码随机访问。封装可以通过关键字private,protected和public实现。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于设计模式的相关问题,主要将装饰器模式的相关内容,指在不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式,希望对大家有帮助。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3汉化版
中文版,非常好用