开闭原则
基本介绍
1) 开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则
2) 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用
方)。用抽象构建框架,用实现扩展细节。
3) 当软件需要变化时,尽量 通过扩展软件实体的行为来实现变化,而 不是通过修改已
有的代码来实现变化。
4) 编程中遵循其它原则,以及使用设计模式的目的就是遵循 开闭原则。
代码发现违背开闭原则的场景
package com.wf.zhang.ocp; public class Ocp { public static void main(String[] args) { GraphicEditor graphicEditor = new GraphicEditor(); //绘制矩形 Rectangle rectangle = new Rectangle(); graphicEditor.drawShape(rectangle); //绘制圆形 Circle circle = new Circle(); graphicEditor.drawShape(circle); } } /** * 使用方 * */ class GraphicEditor { public void drawShape(Shape s) { if (s.m_type == 1) drawRectangle(s); else if (s.m_type == 2) drawCircle(s); } public void drawRectangle(Shape r) { System.out.println(" 矩形 "); } public void drawCircle(Shape r) { 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; } }
需求 需要增加三角形的绘制
package com.wf.zhang.ocp.improve; public class Ocp { public static void main(String[] args) { GraphicEditor graphicEditor = new GraphicEditor(); //绘制矩形 Rectangle rectangle = new Rectangle(); graphicEditor.drawShape(rectangle); //绘制圆形 Circle circle = new Circle(); graphicEditor.drawShape(circle); //绘制三角形 Triangle triangle = new Triangle(); graphicEditor.drawShape(triangle); } } /** * 使用方 * */ 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) drawTriangle(s); } public void drawRectangle(Shape r) { System.out.println(" 矩形 "); } public void drawCircle(Shape r) { System.out.println(" 圆形 "); } //需要增加代码 public void drawTriangle(Shape r) { 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 Triangle extends Shape{ Triangle() { super.m_type = 3; } }
问题
违反了设计模式的ocp原则,即 对扩展开放( 提供方) ,对修改关闭( 使用方)。
即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.
比如我们这时要新增加一个图形种类 三角形,修改的地方较多
解决
思 路 :把创建Shape类做成抽象类,并提供一个抽象的draw方法,让子类去实现即可,
这样我们有新的图形种类时,只需要让新的图形类继承Shape,并实现draw方法即可,
使用方的 代码就不需要修改 -> 满足了开闭原则
package com.wf.zhang.ocp.improve; public class Ocp2 { public static void main(String[] args) { GraphicEditor graphicEditor = new GraphicEditor(); // 绘制矩形 Rectangle rectangle = new Rectangle(); graphicEditor.drawShape(rectangle); // 绘制圆形 Circle circle = new Circle(); graphicEditor.drawShape(circle); // 绘制三角形 Triangle triangle = new Triangle(); graphicEditor.drawShape(triangle); } } /** * 使用方 删掉调用细节 * */ class GraphicEditor { public void drawShape(Shape s) { s.draw(); } } /** * 提供方 定义抽象基类 * */ abstract class Shape { 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 Triangle extends Shape { Triangle() { super.m_type = 3; } @Override public void draw() { System.out.println(" 三角形 "); } }
此时在 增加 新的图形
调用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.wf.zhang.ocp.improve; public class Ocp2 { public static void main(String[] args) { GraphicEditor graphicEditor = new GraphicEditor(); // 绘制矩形 Rectangle rectangle = new Rectangle(); graphicEditor.drawShape(rectangle); // 绘制圆形 Circle circle = new Circle(); graphicEditor.drawShape(circle); // 绘制三角形 Triangle triangle = new Triangle(); graphicEditor.drawShape(triangle); // 绘制其他 Othere othere = new Othere(); graphicEditor.drawShape(othere); } } /** * 使用方 删掉调用细节 * */ class GraphicEditor { public void drawShape(Shape s) { s.draw(); } } /** * 提供方 定义抽象基类 * */ abstract class Shape { 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 Triangle extends Shape { Triangle() { super.m_type = 3; } @Override public void draw() { System.out.println(" 三角形 "); } } class Othere extends Shape { Othere() { super.m_type = 4; } @Override public void draw() { System.out.println(" 其他 "); } }