设计模式七大原则——开闭原则

一、基本介绍

  (1)开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则

  (2)一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。

  (3)当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

  (4)编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。

二、应用实例

  设计一个画图形的功能,类图如下:

  

  说明:GraphicEditor是一个用于画图形的类,其中三个方法分别代表绘制图形drawShape,绘制矩形drawRectangle,绘制圆形drawCircle,Rectangle和Circle都继承自Shape类,drawShape根据传入shape对象的m_type来判断具体是绘制什么图形

   代码实现:

 1 public class OpenClosePrinciple {
 2     public static void main(String[] args) {
 3         GraphicEditor graphicEditor = new GraphicEditor();
 4         graphicEditor.drawShape(new Rectangle());
 5         graphicEditor.drawShape(new Circle());
 6     }
 7 }
 8 
 9 //用于绘图的类
10 class GraphicEditor {
11     //接收Shape对象,根据m_type来绘制不同的图形
12     public void drawShape(Shape shape) {
13         if (shape.m_type == 1) {
14             drawRectangle(shape);
15         } else if (shape.m_type == 2) {
16             drawCircle(shape);
17         } 
18     }
19 
20     public void drawRectangle(Shape rectangle) {
21         System.out.println("绘制矩形");
22     }
23 
24     public void drawCircle(Shape circle) {
25         System.out.println("绘制圆形");
26     }
27 }
28 
29 //基类Shape
30 class Shape {
31     int m_type;
32 }
33 
34 class Rectangle extends Shape {
35     public Rectangle() {
36         super.m_type = 1;
37     }
38 }
39 
40 class Circle extends Shape {
41     public Circle() {
42         super.m_type = 2;
43     }
44 }

  运行结果:

  

   分析:

  (1)优点是比较好理解,简单易操作。

  (2)缺点是违反了设计模式的开闭原则,即对扩展开放(提供方),对修改关闭(使用方)。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.

  (3)比如我们这时要新增加一个图形种类三角形,我们需要做如下修改,修改的地方较多

  新需求:增加绘制三角形功能

  说明:首先我们要新增一个Triangle类继承Shape,并且将其m_type置为3,在GraphicEditor中新增一个drawTriangle方法用于绘制三角形

  代码实现:

 1 public class OpenClosePrinciple {
 2     public static void main(String[] args) {
 3         GraphicEditor graphicEditor = new GraphicEditor();
 4         graphicEditor.drawShape(new Rectangle());
 5         graphicEditor.drawShape(new Circle());
 6         graphicEditor.drawShape(new Triangle());
 7     }
 8 }
 9 
10 //用于绘图的类
11 class GraphicEditor {
12     //接收Shape对象,根据m_type来绘制不同的图形
13     public void drawShape(Shape shape) {
14         if (shape.m_type == 1) {
15             drawRectangle(shape);
16         } else if (shape.m_type == 2) {
17             drawCircle(shape);
18         } else if (shape.m_type == 3) {
19             drawTriangle(shape);
20         }
21     }
22 
23     public void drawRectangle(Shape rectangle) {
24         System.out.println("绘制矩形");
25     }
26 
27     public void drawCircle(Shape circle) {
28         System.out.println("绘制圆形");
29     }
30 
31     public void drawTriangle(Shape triangle) {
32         System.out.println("绘制三角形");
33     }
34 }
35 
36 //基类Shape
37 class Shape {
38     int m_type;
39 }
40 
41 class Rectangle extends Shape {
42     public Rectangle() {
43         super.m_type = 1;
44     }
45 }
46 
47 class Circle extends Shape {
48     public Circle() {
49         super.m_type = 2;
50     }
51 }
52 
53 class Triangle extends Shape {
54     public Triangle() {
55         super.m_type = 3;
56     }
57 }

  运行结果:

  

   分析:虽然我们将功能实现了,但是每次增加新的图形都要这样操作未免太过麻烦,于是我们需要使用开闭原则来对程序进行改进,改进思路是把Shape类做成抽象类,并提供一个抽象的draw方法,让子类去实现即可,这样我们有新的图形种类时,只需要让新的图形类继承 Shape,并实现 draw 方法即可,使用方的代码就不需要修改,这样就满足了开闭原则

  代码实现:

 1 public class OpenClosePrinciple {
 2     public static void main(String[] args) {
 3         GraphicEditor graphicEditor = new GraphicEditor();
 4         graphicEditor.drawShape(new Rectangle());
 5         graphicEditor.drawShape(new Circle());
 6         graphicEditor.drawShape(new Triangle());
 7     }
 8 }
 9 
10 //用于绘图的类
11 class GraphicEditor {
12     public void drawShape(Shape shape) {
13         shape.draw();
14     }
15 }
16 
17 //基类Shape
18 abstract class Shape {
19     int m_type;
20 
21     //抽象方法:绘制图形
22     public abstract void draw();
23 }
24 
25 class Rectangle extends Shape {
26     public Rectangle() {
27         super.m_type = 1;
28     }
29 
30     @Override
31     public void draw() {
32         System.out.println("绘制矩形");
33     }
34 }
35 
36 class Circle extends Shape {
37     public Circle() {
38         super.m_type = 2;
39     }
40 
41     @Override
42     public void draw() {
43         System.out.println("绘制圆形");
44     }
45 }
46 
47 class Triangle extends Shape {
48     public Triangle() {
49         super.m_type = 3;
50     }
51 
52     @Override
53     public void draw() {
54         System.out.println("绘制三角形");
55     }
56 }

  运行结果:

  

   分析:运行结果与上面的代码相同,但是如果我们这时候新增一个绘制梯形的需求,只需要扩展代码即可,不需要修改原有代码

  代码实现:

 1 public class OpenClosePrinciple {
 2     public static void main(String[] args) {
 3         GraphicEditor graphicEditor = new GraphicEditor();
 4         graphicEditor.drawShape(new Rectangle());
 5         graphicEditor.drawShape(new Circle());
 6         graphicEditor.drawShape(new Triangle());
 7         graphicEditor.drawShape(new Trapezoid());
 8     }
 9 }
10 
11 //用于绘图的类
12 class GraphicEditor {
13     public void drawShape(Shape shape) {
14         shape.draw();
15     }
16 }
17 
18 //基类Shape
19 abstract class Shape {
20     int m_type;
21 
22     //抽象方法:绘制图形
23     public abstract void draw();
24 }
25 
26 class Rectangle extends Shape {
27     public Rectangle() {
28         super.m_type = 1;
29     }
30 
31     @Override
32     public void draw() {
33         System.out.println("绘制矩形");
34     }
35 }
36 
37 class Circle extends Shape {
38     public Circle() {
39         super.m_type = 2;
40     }
41 
42     @Override
43     public void draw() {
44         System.out.println("绘制圆形");
45     }
46 }
47 
48 class Triangle extends Shape {
49     public Triangle() {
50         super.m_type = 3;
51     }
52 
53     @Override
54     public void draw() {
55         System.out.println("绘制三角形");
56     }
57 }
58 
59 class Trapezoid extends Shape {
60     public Trapezoid() {
61         super.m_type = 4;
62     }
63 
64     @Override
65     public void draw() {
66         System.out.println("绘制梯形");
67     }
68 }

  运行结果:

  

   分析:这时候我们发现,仅仅增加了一个新的类Trapezoid继承Shape并且实现了draw方法就实现了功能,在扩展了代码功能的同时也没有对原有代码进行较大的改动,这就是开闭原则的魅力所在

原文地址:https://www.cnblogs.com/yijiahao/p/14380045.html