概要
何谓开放关闭,其实就是对扩展是开放的,对修改是关闭的。前半句好理解,后半句什么意思?进一步说明,就是扩展的同时对固有既定模块是不需要再修改的,如果还要问什么是固有既定模块,抱歉,文字还真不好解释,到后面穿插实例再来说明吧。目的
对扩展开发,对修改关闭
实例与效果
先看个例子,比如我们需要一个封装访问MySql数据库的类。定义一些数据库操作API供外部调用,代码和类图如下所示:
class Database { public: void connect(); void execute(); void commit(); void rollback(); };
然后你兴致勃勃地开始用了。然后有一天,需求又增加了,需要支持SQL Server了,你可能觉得,这很简单,类里加个Type参数,if-else区别处理,然后搞定。但是,需求继续膨胀,SQLite,Oracle.....都要支持,好,继续else-if,else-if的加吧,加着加着你突然发现原来运行正常的MySql出现异常了,debug半天发现原来耦合太多,你改着改着就把原来既有的改错了。让我们一起来反省下,如果开始就考虑下OCP呢?卡看这样做是不是更好。
class IDatabase { public: virtual void connect() = 0; virtual void execute() = 0; virtual void commit() = 0; virtual void rollback() = 0; }; class MySqlDB : public IDatabase { public: virtual void connect(); virtual void execute(); virtual void commit(); virtual void rollback(); };
好,让需求变化的更疯狂些吧, SQL Server, SQLite,Oracle.....只是每次追加一个继承于 IDatabase独立的类而已,而既有的数据库封装类是不需要任何改动的。这里的 IDatabase, MySqlDB就属于前面所谓的固有的既定模块,而它们在你扩展时是不受影响的。而调用方Client,也只是需要改变创建的数据库对象而已。
现在关于OCP,有那么点感觉了吧?这就是所谓的对扩展开放,对修改关闭。
最后声明一点, 所有OO原则都是个宏观的概念,而我所 举的例子都相对比较片面,像这个例子说白了也就是个多态的应用罢了,只算个特例而已。