设计原则之开放闭合原则(OCP)
来源:互联网 发布:java 格式化上午下午 编辑:程序博客网 时间:2024/06/01 12:21
在《敏捷软件开发-原则、模式与实践》一书中,对开放闭合原则的定义为:
软件实体(类、模块、函数等)应该是可以扩展的,但是不可以修改。
简言之,两个特征:
1、对于扩展是开放的;
2、对于修改是关闭的
这两点特征貌似自相矛盾,怎么样在不改动模块源码的情况下去更改他的行为呢?如果不更改一个模块,又怎么能够去改变它的功能呢?
答案很简单,就是抽象。模块可能对抽象体进行操作。由于模块依赖于一个固定的抽象体,所以他对于更改可以是封闭的。同时,通过从这个抽象体去派生,可以扩展此模块的行为。
在设计原则开篇一文中已经举例说明了如何应用这个原则。在这篇文章中再举一个例子,帮助大家加深认识。
如果你有去看zend framework的源码,其中有一段代码是用来解析配置文件的,这次就拿这个案例来举例。
version1:
有多个配置文件:config.php、config.json、config.xml
config.php:
<?phpreturn array('database' => array('host' => '127.0.0.1','username' => 'root','password' => '','dbname' => 'test'));config.json:
{"database":{"host":"127.0.0.1","username":"root","password":"","dbname":"test"}}config.xml:
<?xml version="1.0" encoding="ISO-8859-1"?><config><database><host>127.0.0.1</host><username>root</username><password></password><dbname>test</dbname></database></config>
我们将配置文件交给config类去处理:
public function configToArray($configFile){ $extension = pathinfo($configFile, PATHINFO_EXTENSION); $config = array();switch ($extension) { case 'php': $config = require_once $configFile; break; case 'xml': $xml = simplexml_load_file($configFile); return json_decode(json_encode($xml), true); case 'json': $config = json_decode(file_get_contents($configFile), true); break; } foreach ($config as $key => $value) { $this->set($key, $value); } }
这样的弊端在于,后期如果希望使用新的配置文件,比如ini文件、yaml文件等,我们就需要到switch语句里面去新增case。
现在来看version 2的设计:
首先声明了一个接口Configuration:
<?phpinterface Configuration{ public function toArray($configFilePath);}然后新增了3个具体的实现类:
jsonConfiguration.php
<?phprequire_once "configuration.php";class JsonConfiguration implements Configuration{ public function toArray($configFilePath){ return json_decode(file_get_contents($configFilePath), true); }}phpConfiguration.php
<?phprequire_once "configuration.php";class phpConfiguration implements Configuration{ public function toArray($configFilePath){ $config = require_once $configFilePath; return $config; }}xmlConfiguration.php
<?phprequire_once "configuration.php";class XmlConfiguration implements Configuration{ public function toArray($configFilePath){ $xml = simplexml_load_file($configFilePath); return json_decode(json_encode($xml), true); }}这样config类中的代码就可以修改为:
public function configToArray(Configuration $configuration){ $config = is_array($configuration->toArray($this->configFilePath)) ? $configuration->toArray($this->configFilePath) : array(); foreach ($config as $key => $value) { $this->set($key, $value); } }
这样我们想再增加一个配置文件时,就可以新增一个实现类就可以了。也就做到了“对修改关闭,对扩展开放”了。
这个案例和设计原则开篇一文中提到的案例非常相似,可以概括为“如何将if/else转换为抽象”和“如何将switch转换为抽象”,
在许多方面,OCP都是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处:灵活性、可重用性和可维护性。然而,并不是说只要使用一种面向对象语言就是遵循了这个原则。对于应用程序中的每个部分都肆意地进行抽象同样不是一个好主意。正确的做法是,开发人员应该仅仅对程序中呈现出频繁变化的那些部分做出抽象。拒绝不成熟的抽象和抽象本身一样重要。
- 设计原则之开放闭合原则(OCP)
- 设计模式--开放/封闭原则(OCP)
- 设计原则——开放封闭原则(OCP)
- 设计模式六大原则(5):开放封闭原则(OCP)
- 设计模式六大原则(六)-- 开放封闭原则 ( OCP )
- 软件设计之 开放-封闭原则(OCP)
- 开放闭合原则
- 开放闭合原则
- 开放-封闭原则(OCP)
- 开放-封闭原则(OCP)
- 开放封闭原则(OCP)
- 开放-封闭原则(OCP)
- 开放-封闭原则(OCP)
- 开放-封闭原则(OCP)
- 【设计模式攻略】OO设计原则之OCP-开放-关闭原则
- IOS设计模式的六大设计原则之开放-关闭原则(OCP,Open-Close Principle)
- 设计模式 开放封闭原则 OCP
- 面向对象设计原则--开放封闭原则(OCP)
- SDL播放yuv数据
- PageRank及其MapReduce实现
- [学习笔记]JavaScript基础--淡入淡出
- muduo::TcpConnection分析
- 周赛 简单的bfs
- 设计原则之开放闭合原则(OCP)
- codeforces Round #Pi (div.2) 567ABCD
- 富甲天下3存档修改
- 用户'sa'登录失败(DataGridView)
- OC学习笔记
- 简历
- 模拟 codeforces567B Berland National Library
- 黑马程序员---struts2学习笔记之七(表单验证)
- Android学习笔记之常用控件