java设计模式学习笔记--开闭原则
基本介绍
1、开闭(ocp)原则时编程中最基础、最重要的设计原则
2、一个软件实体如类、木块和函数应该对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节。即对提供方开放,对使用方关闭。
3、当软件需要变化时,尽量通过扩展软件实体的行为类实现变化,而不是通过修改已有代码来实现变化
4、编程中遵循其他原则,以及使用设计模式的目的就是遵循开闭原则。
先来一段代码展示
public class Ocp {
public static void main(String[] args) {
// 使用,看看存在的问题
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawCircle(new Shape());
graphicEditor.drawRectangle(new Shape());
graphicEditor.drawOther(new Shape());
}
}
//这是一个用于绘图的类
class GraphicEditor {
public void drawShape(Shape s) {
if (s.m_type == 1) {
drawRectangle(s);
} else if (s.m_type == 2) {
drawCircle(s);
} else if (s.m_type == 3) {
// 需在使用方添加(else if)代码快
drawOther(s);
}
}
public void drawRectangle(Shape s) {
System.out.println("这是矩形");
}
public void drawCircle(Shape s) {
System.out.println("这是圆形");
}
// 需在使用方添加新的方法
public void drawOther(Shape s) {
System.out.println("这是其他图形");
}
}
class Shape {
int m_type;
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
}
class Other extends Shape {
Other() {
super.m_type = 3;
}
}
分析这段代码中存在的问题
1、代码简单易懂,思路清晰。
2、但违反了设计模式的ocp原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码。
3、每增加一个功能都要需在使用方添加(else if)代码快,过多的(else if)会使代码过于臃肿,运行效率不高。
改进思路
创建一个Shape类,并提供一个抽象的draw()方法,让子类实现该方法。每当增加一个图形种类时,让该图形种类继承Shape类,并实现draw()方法。这样,使用方只需编写一个drawShape方法,传入一个图形类的对象,即可使用其相应的绘图方法。只需要修改提供方的代码,不需要修改使用方的代码,遵循ocp原则
使用ocp原则
public class Ocp {
public static void main(String[] args) {
// 遵循ocp原则
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
graphicEditor.drawShape(new Other());
}
}
//这是一个用于绘图的类,[使用方]
class GraphicEditor {
// 接收Shape对象,调用其对应的draw方法
public void drawShape(Shape s) {
s.draw();
}
}
//Shape类,基类
abstract class Shape {
public int m_type;
public abstract void draw(); // 抽象方法
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
@Override
public void draw() {
System.out.println("这是矩形");
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
@Override
public void draw() {
System.out.println("这是圆形");
}
}
//新增一个其他图形
class Other extends Shape {
Other() {
super.m_type = 3;
}
@Override
public void draw() {
System.out.println("这是其他图形");
}
}
java设计模式学习笔记--开闭原则的更多相关文章
- java设计模式学习笔记--接口隔离原则
接口隔离原则简述 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应建立在最小的接口上 应用场景 如下UML图 类A通过接口Interface1依赖类B,类C通过接口Interface1依赖类 ...
- java设计模式学习笔记--单一职责原则
单一职责原则注意事项和细节 1.降低类的复杂度,一个类只负责一项职责 2.提高可读性,可维护性 3.降低变更引起的风险 4.通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单 ...
- java设计模式学习笔记--依赖倒转原则
依赖倒转原则简述 1.高层模块不应该依赖低层模块,二者都应该依赖其抽象 2.抽象不应该依赖细节,细节应该依赖抽象 3.依赖倒转得中心思想时面向接口编程 4.依赖倒转原则时基于这样得设计理念:相对于细节 ...
- java设计模式学习笔记——里氏替换原则
oo中的继承性的思考和说明 1.继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有的子类必须遵循这些七月,但是如果子类对这些已经实现的方法任意修改,就会对 ...
- java设计模式学习笔记--浅谈设计模式
设计模式的目的 编写软件的过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战.设计模式为了让程序具有更好的 1.代码重用性(即:相同功能的代码,不用多次编写) ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- Java设计模式学习笔记(四) 抽象工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
- java设计模式学习笔记
简介 设计模式可以分为五类 接口型 模式:适配器模式,外观模式,合成模式,桥接模式 职责型 模式:单例模式,观察者模式,调停者模式,代理模式,职责链模式,享元模式 构造型 模式:构建者模式,工厂方法模 ...
随机推荐
- 痞子衡嵌入式:ARM Cortex-M内核那些事(3.2)- 安全模块看特性(M23/33/35P)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Cortex-M功能模块,不过侧重点是三款安全特性处理器. ARM Cortex-M处理器家族发展至今(2020),已有8代产品 ...
- 【java基础】String、StringBuilder和StringBuffer的区别
关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.三者在执行速度方面的比较:StringBuilder > String ...
- 废旧手机利用之装一个Linux系统
开篇: 在废旧手机变废为宝的路上一直没有停下,做过电脑遥控器,家居监控器,给电脑扩展屏幕以及跟着大佬学过智能机器人,但是都是一时兴趣,除了家具监控器目前正在使用之外其他也没有使用了. 最近在学习Lin ...
- 自用代码css获取任意网址的/favicon.ico的方法教程
尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用这种办法获取 如果有好的方法望评论告知 谢谢 <img :ng-src="'http://'+list.url+'/fav ...
- CSS-12-盒子模型
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 基于快排思想的第(前)k大(小)
算法思路就是根据快排的partition,先随机选择一个分隔元素(或a[0]),将数组分为[小于a[p]的元素] a[p] [大于a[p]的元素],如果这时候n-p+1等于k的话,a[p]就是所求的第 ...
- maven项目pom.xml加载本地jar,自定义jar
将jar放到resource目录下面: pom添加配置 <!-- 加载IK自定义 依赖--> <dependency> <groupId>com.ik.up< ...
- web自动化环境配置
1.下载chrome浏览器对应版本的驱动 下载地址:https://npm.taobao.org/mirrors/chromedriver 2.下载后将chromedriver放到python安装路径 ...
- Leetcode 题目整理-3 Palindrome Number & Roman to Integer
9. Palindrome Number Determine whether an integer is a palindrome. Do this without extra space. clic ...
- nginx的进程结构实例演示
nginx父子进程之间是使用信号进行管理的. nginx -s reload 会使之前的nginx子进程退出,生成新的nginx子进程 或者kill -SIGHUP 9170 kill -SIGTER ...