开放-封闭原则(OCP)

开放-封闭原则(The Open-Close Principle)

软件实体(类、模块、函数等)应该是可以扩展的,但是不可以修改的。

两个特征

1、对于扩展是开放的(Open for extension);

2、对于更改是封闭的(Close for modification)。

关键是抽象

既不开放又不封闭的Client

        Client类和Server类都是具体类。Client类使用Server类。如果我们希望Client对象使用另外一个不同的服务器对象,那么就必须把Client类中使用Server类的地方更改为新的服务器类。

Strategy 模式:既开放又封闭的Client

        Client需要实现一些功能,可以使用ClientInterface接口去描述那些功能。子类可以选择它们的方式去实现这个接口。这样,就可以通过创建ClientInteface的新的子类的方式去扩展、更改Client的行为。

        Why?把接口命名为ClientInterface,而非AbstractServer。因为抽象类和Client的关系更紧密。

Shape 应用程序

1、违反OCP

        drawAllShapes()不符合OCP,因为它对于新的形状类型的添加不是封闭的。每添加一种新的形状类型,都必须要更改这个函数。

public enum ShapeTpye {CIRCLE, SQUARE
}public class Shape {ShapeType itsType;
}public class Circle extends Shape {ShapeType itsType;double itsRadius;Point itsCenter;
}public class Square extends Shape {ShapeType itsType;double itsSide;Point itsTopLeft;
}//----------------------drawAllShapes---------------------
public void drawAllShapes(ShapePointer list[], int n) {int i;for (int i=0; i<n; i++) {Shape s = list[i];switch (s.itsType) {case SQUARE:drawSquare((Square)s);break;case CIRCLE:drawCircle((Circle)s);break;}}}

2、遵循OCP

        drawAllShapes()符合OCP,对它的改动是增加新的模块,以及为了能够实例化新类型而围绕main的改动。

public interface Shape {public void draw();
}public class Square implements Shape {public void draw() {// 业务细节...}
}public class Circle implements Shape {public void draw() {// 业务细节...}
}//----------------------drawAllShapes---------------------
public void drawAllShape(List<Shape> list) {for(Shape s : list) {s.draw();}
}

3、预测变化与“合适”的结构

        假设我们要求所有的圆必须在正方形之前绘制,drawAllShapes()无法对这种变化做到封闭。

        无论模块是多么的“封闭”,都会存在一些无法对之封闭的变化。不存在对所有情况都合适的模型。既然不可能完全封闭,那么就必须有策略地对待这个问题。设计人员必须对他设计的模型应该对哪种变化封闭做出选择。他必须先猜测出最有可能发生变化种类,然后构造抽象来隔离那些变化。

        遵循OCP的代价也是昂贵的。创建正确的抽象是要花费时间和精力的。同时,那些抽象也增加了软件设计的复杂性。因而,我们希望把OCP的应用限定在可能会发生的变化上。

应对之道

1、只受一次愚弄

        谚语:“愚弄我一次,应该羞愧的是你;再次愚弄我,应该羞愧的是我。”这意味着在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后同类变化。

2、刺激变化

        如果我们决定接受第一颗子弹,那么子弹到来的越早越好、越快就对我们越有利。

首先编写测试——迫使系统可测试,构建了使系统可测试的抽象。

使用很短的迭代周期进行开发

在加入基础结构前就开发特性,并经常性地把那些特性展示给涉众。

首先开发最重要的特性

尽早地、经常性地发布软件

使用抽象获得显式封闭

public interface Shape extends Comparable<Shape> {public void draw();public boolean precedes(Shape s);
}public class Circle implements Shape {// 根据对象类型排序...public boolean precedes(Shape s) {if (s instanceof Square) {return true;}return false;}public int compare(Shape s1, Shape s2) {if (s1.precedes(s2)) {return 1;}return -1;}
}public void drawAllShapes(List<Shape> list) {sort(list);for (Shape s : list) {s.draw();}
}

表格驱动法获取封闭性

public class Shape {private static final Class<Shape>[] typeOrderTable = new Class[]{Circle.class, Square.class};public void draw() {//...}public boolean precedes(Shape s) {Class thisType = this.getClass();Class argType = s.getClass();boolean done = false;int thisOrder = -1;int argOrder = -1;for (int i=0; !done; i++) {Class tableEntity = typeOrderTable[i];if (tableEntity.equals(thisType)) {thisOrder = i;}if (tableEntity.equeals(argType)) {argOrder = i;}if (thisOrder >= 0 && argType >= 0) {done = true;}}return thisOrder < argOrder;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/497515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

风向2018 | AI 突围

来源&#xff1a;36氪概要&#xff1a;回到战场&#xff0c;考验各家公司CEO和谋士的时刻&#xff0c;已经到来。问&#xff1a;2017年AI行业最大的进展是什么&#xff1f;答&#xff1a;创业公司的估值。高估值&#xff0c;曾将AI初创公司带上高光的创投舞台&#xff0c;也正将…

php return 值_php return的用法是什么

php return的用法&#xff1a;1、通过“return expression”语法返回一个表达式结果&#xff1b;2、使用“return(expr)”语法返回函数表达式&#xff1b;3、直接使用return返回值即可。本文操作环境&#xff1a;Windows7系统、PHP7.1、Dell G3电脑。基本用法&#xff1a;a)、r…

Liskov替换原则(LSP)

Liskov替换原则&#xff08;The Liskov Substitution Principle&#xff09; 子类型&#xff08;subtype&#xff09;必须能够替换掉它们的基类型&#xff08;base type&#xff09;。 一个违反LSP的简单例子 public class AntiLspDemo {public void drawShape(final Shape …

谷歌放出AI平民化大招: 李飞飞宣布推出AutoML云平台,让普通企业也能用上深度学习

作者&#xff1a;杨晓凡概要&#xff1a;谷歌云机器学习平台&#xff08;Google Cloud AI&#xff09;自从上线以来就以预训练的、可以直接调用的高效机器学习模型吸引了许多企业级用户在其上构建简单的机器学习应用。谷歌云机器学习平台&#xff08;Google Cloud AI&#xff0…

php 强制返回,php – 我可以强制抽象类的方法返回一些东西吗?

在PHP中,你不能“强制”一个方法来返回任何东西 – 即使使用抽象类/方法,也不可能使用接口.您可以做的最好的事情是表明实现应该返回一些内容,使用注释 – 但您不能强迫人们这样做&#xff1a;/*** param string $a blah blah* return int The return value blah blah*/public …

AI博弈论:DeepMind让智能体在非对称博弈中找纳什均衡

Root 林鳞 编译自 DeepMind官方博客量子位 出品 | 公众号 QbitAI随着人工智能系统在现实世界中扮演越来越重要的角色&#xff0c;理解不同的系统如何相互作用至关重要。刚刚&#xff0c;DeepMind发表了一篇名为Symmetric Decomposition of Asymmetric Games的论文。在这篇论文中…

php ie 下载 乱码,php ie下载文件名乱码怎么办

php ie下载文件名乱码的解决办法&#xff1a;1、通过header方法解决乱码&#xff1b;2、通过“function remote_filesize($uri,$user,$pw) {...}”等方法解决乱码。php文件下载IE文件名乱码问题一直用chrome浏览器&#xff0c;没发现问题。今天用ie6&#xff0c;发现文件下载时…

无人驾驶技术排名:百度居中游,苹果特斯拉垫底 | 行业

来源&#xff1a;网易科技概要&#xff1a;其调查研究显示&#xff0c;无人驾驶汽车行业的现状已经发生了天翻地覆的变化&#xff0c;而特斯拉、苹果公司在今年的排名垫底。1月17日消息&#xff0c;据CNET网站报道&#xff0c;日前&#xff0c;美国市场研究机构Navigant Resear…

h5 换脸 php,【部分原创】python实现视频内的face swap(换脸)

1.准备工作&#xff0c;按博主的环境为准Python 3.5Opencv 3Tensorflow 1.3.1Keras 2cudnn和CUDA&#xff0c;如果你的GPU足够厉害并且支持的话&#xff0c;可以选择安装那就先安装起来&#xff0c;有兴趣的朋友给我个暗示&#xff0c;好让我有动力写下去&#xff0c;想实现整套…

接口隔离原则(ISP)

接口隔离原则&#xff08;The Interface Segregation Interface&#xff09; 这个原则用来处理“胖&#xff08;fat&#xff09;”接口&#xff08;类的接口不是内聚的&#xff09;所具有的缺点。“胖”接口可以分解成多组方法。 考虑一个安全系统&#xff0c;有一些Door对象&a…

马歇尔·赫伯特:人工智能的前沿技术与实例分析

来源&#xff1a;中国人工智能学会2017年12月11日&#xff0c;国际知名机器人专家、美国卡耐基梅隆大学机器人研究所所长马歇尔赫伯特(Martial Hebert)教授和首席科学家大卫伯恩(David Bourne)教授访问了中国科学技术大学参观中科大机器人实验室并作演讲。演讲人简介&#xff1…

php xssclean,php – Codeigniter xss_clean困境

基本上XSS是一个OUTPUT问题 – 但Codeigniter将其作为INPUT问题处理.Can someone elaborate how it’s bad…问题是xss_clean会改变你的INPUT – 这意味着在某些情况下(比如你所描述的密码问题)输入不是预期的.…or at least give 1 most probable scenario where it can be ex…

ActiveMQ消费者平滑关闭

平滑关闭的思路就是让正在执行的任务线程正常执行完毕&#xff0c;然后再关闭JVM。在JVM关闭之前触发一个shutdown hook&#xff0c;jvm自带这个hook&#xff0c;在java启动时候就可以注册这样的hook。 ##1、简述JVM关闭钩子&#xff08;shutdown hook&#xff09; 首先JVM的关…

二叉堆时间复杂度 php,二叉堆(Binary Heap)

二叉堆这个数据结构有点意思&#xff0c;自己做了个总结&#xff0c;内容结构如下&#xff1a;二叉堆性质二叉堆操作应用二叉堆性质&#xff1a;堆(Heap)是一个可以被看成近似完全二叉树的结构&#xff0c;具有完全二叉树的特性&#xff1a;缺少的叶子节点总是位于右子节点n个节…

产业丨一文读懂人工智能产业链,未来10年2000亿美元市场

来源&#xff1a;国防科技信息网概要&#xff1a;针对人工智能产业链&#xff0c;主要有三个核心&#xff1a;基础技术、人工智能技术及人工智能应用&#xff0c;本文将从主要从这三个方面进行梳理。人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩…

Java获取并Kill系统进程

原理&#xff1a;获取系统所有进程列表&#xff0c;遍历&#xff0c;然后进行模糊匹配&#xff0c;将匹配到的进程杀死&#xff01; 作用&#xff1a;保证在系统中只有一个程序进程实例。 /*** 确保系统中只有一个程序实例* 1.如果客户端启动前&#xff0c;操作系统中有残留进…

2017年高性能计算领域的成功与失败

来源&#xff1a;中科院信息科技战略情报概要&#xff1a;2017年&#xff0c;机器学习和各种人工智能应用在高性能计算领域持续发挥着重要影响力。2017年12月9日&#xff0c;TOP500官网刊文总结了高性能计算在2017年取得的新进展&#xff0c;以及未来发展趋势&#xff0c;主要内…

php保存rar,php 解压rar文件

对于zip文件网上的例子很多&#xff0c;rar文件解压php没有直接支持&#xff0c;可以用pecl 到http://pecl.php.net/package/rar 下载对应版本的 非线程安全的dll 然后扔到php的 ext目录下。 打开php.ini. 加一行 extensionphp_rar.dll 重启web服务器 和php public function _u…

ProcessBuilder执行bash脚本

我正在尝试从Java执行bash脚本,它返回错误/ bin / bash&#xff1a;’/ home / nika / NetBeansProjects / Parallel Framework / process-executor.sh’&#xff1a;没有这样的文件或目录,我正在使用ubuntu使用netbeans8& 14.04 jdk8. 这是我的代码&#xff1a; public …

php读取云平台数据库,读取Read · ThinkPHP5+数据库和模型 · 看云

#### Db类实现读取单个记录~~~$user Db::table(user)->where(id, 1)->find();//或者$user Db::table(user)->find(1);echo $user[id];echo $user[name];~~~模型实现读取单个记录要比Db类简单很多&#xff0c;而且更加符合对象的设计。~~~$user User::get(1);echo $…