【设计模式笔记】开闭原则

开闭原则

OCP / Open Closed Principle


尚硅谷设计模式-学习笔记


----------------开闭基本介绍

  1. 开闭原则是编程最基础,最重要的设计原则
  2. 一个软件实体如类,模块,方法,应该对扩展开放(对提供方),对修改关闭(对使用方); 用抽象构建框架,用实现扩展细节
  3. 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化
  4. 编程中遵循其他原则,以及使用设计模式的目的就是遵循开闭原则。

----------------开闭原则实例


实例简介:完成一个画图形的功能
Example:传统方式


   public class OCP1 {
       public static void main(String[] args) {
           //使用看看存在的问题是什么
           
           GraphicEditor graphicEditor = new GraphicEditor();
           graphicEditor.drawShape(new Rectangle());
           graphicEditor.drawShape(new Circle());
       }
   }

   //这是一个用于绘图的类[使用方]
   //接受Shape对象,根据其type绘制不同的图形
   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("绘制圆形");
       }
   }

   //Shape基类
   class Shape{
       int m_type;
   }

   class Rectangle extends Shape{
       Rectangle(){
           super.m_type = 1;	
       }
   }

   class Circle extends Shape{
       Circle(){
           super.m_type = 2;
       }
   }


这个例子运行良好,那么它的优缺点又是什么呢?

  1. 优点是比较好理解,简单易操作
  2. 缺点是违反了设计模式的OCP原则,即对扩展开放,对修改关闭。
    即当我们要给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码
  3. 我们可以观察一下,如果要新增加一个图形种类,我们需要做如下修改


Example:传统方式 在上面的example基础上 添加一个画三角形的功能

	 public class OCP2 {
	     public static void main(String[] args) {
	         
	         GraphicEditor graphicEditor = new GraphicEditor();
	         graphicEditor.drawShape(new Rectangle());
	         graphicEditor.drawShape(new Circle());
	         
	         //画一个三角形
	         graphicEditor.drawShape(new Triangle());
	     }
	 }
	
	 //使用方修改了代码,还增加了新的方法
	 class GraphicEditor{
	     public void drawShape(Shape s) {
	         
	         if(s.m_type ==1) {
	             drawRectangle(s);
	         }else if (s.m_type == 2) {
	             drawCircle(s);
	         }
	         
	         //这里还要增加一个条件判断,判断m_type == 3
	         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;
	     }
	 }
	
	 //新增加一个三角形的类,继承Shape
	 class Triangle extends Shape{
	     Triangle(){
	         super.m_type = 3;	
	     }
	 }

问题:

使用方的类修改的地方较多,而且还在使用方增加了新的方法

解决方法:

思路: 把创建Shape类作为抽象类,并提供一个抽象的draw方法,让子类去实现。

这样我们有新的图形种类时,只需要让新的图形类继承Shape,并实现draw方法即可,使用方的代码就不需要修改了。



Example:改进后的方式

	public class OCP3 {
	    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 OtherShape());
	    }
	}
	
	//这是一个用于绘图的类[使用方]
	//接受Shape对象,根据其type绘制不同的图形
	class GraphicEditor{
	
	    //直接调用各自的draw方法
	    public void drawShape(Shape r) {
	        r.draw();
	    }	
	}
	
	//Shape 抽象类
	abstract class Shape{	
	    
	    //定义了一个抽象方法
	    public abstract void draw();
	
	//分别实现各自的抽象方法
	}
	class Rectangle extends Shape{
	    public void draw() {
	        System.out.println("绘制矩形");
	    }
	}
	
	class Circle extends Shape{
	    public void draw() {
	        System.out.println("绘制圆形");
	    }
	}
	
	class Triangle extends Shape{
	    public void draw() {
	        System.out.println("绘制三角形");
	    }
	}
	
	//假设我们再新增一个图形,只需要添加一个类就好了。
	//并没有修改使用方,满足了OCP原则,
	
	class OtherShape extends Shape{
	    public void draw() {
	        System.out.println("绘制其他图形");
	    }
	}

你可能感兴趣的:(设计模式学习笔记)