1.基本介绍
- 开闭原则(Open Closed Principle)是编程中最基础,最重要的设计原则
- 一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节
- 当软性需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化
- 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则
2.应用案例
-
案例描述
根据给定不同的类型画出不同的图形 -
常规写法
public class OpenClosed { public static void main(String[] args) { //使用看看存在的问题 GraphicEditor graphicEditor = new GraphicEditor(); graphicEditor.drawShape(new Rectangle()); graphicEditor.drawShape(new Circle()); graphicEditor.drawShape(new Triangle()); } } //这是一个用于绘图的类 [使用方] class GraphicEditor { //接收Shape对象,然后根据type,来绘制不同的图形 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("三角形"); } } //Shape类,基类 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; } }
上面的方法是比较好理解,简单易操作,但是违反了开闭原则,即对扩展开放,对修改关闭。即当我们需要给类增加新功能的时候,尽量不要修改代码,或者尽可能少修改代码。
上面的例子,我们需要新增一个图形种类时,修改的地方比较多,也会画图类GraphicEditor 进行新增画其它类型的方法改进思路:
把创建Shape类做出抽象类,并提供一个抽象draw方法,让子类去实现即可,这样当需要新的图形时,只需要让新的图形继承Shape,并实现draw方法即可。这样使用方的代码就不需要修改,满足开闭原则 -
改进后代码
public class OpenClosed { public static void main(String[] args) { //使用看看存在的问题 GraphicEditor graphicEditor = new GraphicEditor(); graphicEditor.drawShape(new Rectangle()); graphicEditor.drawShape(new Circle()); graphicEditor.drawShape(new Triangle()); graphicEditor.drawShape(new OtherGraphic()); } } //这是一个用于绘图的类 [使用方] class GraphicEditor { //接收Shape对象,调用draw方法 public void drawShape(Shape s) { s.draw(); } } //Shape类,基类 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 OtherGraphic extends Shape { OtherGraphic() { super.m_type = 4; } @Override public void draw() { System.out.println("其它图形"); } }
3.注意事项和细节
- 开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段
- 开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码