zoukankan      html  css  js  c++  java
  • 设计模式七大原则——开闭原则

    一、基本介绍

      (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方法就实现了功能,在扩展了代码功能的同时也没有对原有代码进行较大的改动,这就是开闭原则的魅力所在

  • 相关阅读:
    FIREDAC(DELPHI10 or 10.1)提交数据给ORACLE数据库的一个不是BUG的BUG
    分布式系统的软肋——数据一致性
    原子操作
    Android---观察者模式的简单实现demo
    Android -- 获取网络数据并将数据存到本地数据库中
    加密模式
    Vue.js——vue-resource全攻略
    VUE---Missing space before function parentheses
    css:子元素div 上下左右居中方法总结
    扒取网站的源代码
  • 原文地址:https://www.cnblogs.com/yijiahao/p/14380045.html
Copyright © 2011-2022 走看看