1. 程式人生 > 其它 >【設計模式】七大設計原則(三)—— 開閉原則(Open Close Principle)

【設計模式】七大設計原則(三)—— 開閉原則(Open Close Principle)

開閉原則描述

  • 開閉原則是程式設計中最基礎、最重要的原則

  • 一個軟體實體如類,模組和函式應該對擴充套件開發(對提供方),對修改關閉(對使用方)。用抽象構成框架,用實現擴充套件細節。

  • 當軟體需要變化時,儘量通過擴充套件軟體實體的行為來實現變化,而不是通過修改已有程式碼來實現變化。

  • 程式設計中遵循其他原則,以及使用設計模式的目的就是遵循開閉原則。


示例分析

需求: 有圓形, 有橢圓形, 根據要求畫出相應的形狀

//這是一個用來繪圖的類
public class GraphicEditor {
    //接收Shape物件,然後根據type,來繪製不同的圖形
    public void draw(Shape s) {
        if (s.m_type == 1) {
            drawRectangle();
        } else if(s.m_type == 2) {
            drawCircle();
        }
    }

    //繪製矩形
    public void drawRectangle() {
        System.out.println("繪製矩形");
    }

    //繪製圓形
    public void drawCircle() {
        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;
        }
    }

}

然後我們來使用一下看看有什麼問題

public static void main(String[] args){
    GraphicEditor graphicEditor = new GraphicEditor();
    graphicEditor.drawShape(new Rectangle());
    graphicEditor.drawShape(new Circle());
}

首先這樣寫的好處是比較好理解,簡單易操作。缺點就是違反了設計模式的ocp原則,即對擴充套件開發,對修改關閉。即當我們給類增加新功能的時候,儘量不修改程式碼,或者儘可能少修改程式碼。比如我們這時要新增一個圖形種類,需喲要修改的地方太多了。

比如現在我要新增一個畫三角形功能

//新增畫三角形
class Triangle extends Shape{
    Triangle(){
	super.m_type = 3;
	}
}
//使用方
public class GraphicEditor {
    //接收Shape物件,然後根據type,來繪製不同的圖形
    public void draw(Shape shape) {
        if (s.m_type == 1) {
            drawRectangle();
        } else if(s.m_type == 2) {
            drawCircle();
        } else if(s.m_type == 3){
            drawTriangle(s);
        }
    }

    //繪製矩形
    public void drawRectangle() {
        System.out.println("繪製矩形");
    }

    //繪製圓形
    public void drawCircle() {
        System.out.println("繪製圓形");
    }

    //繪製三角形
    public void drawTriangle(s){
        System.out.println("繪製三角形");
    }

如你所見,我們單單只是新增一個新的繪製三角形的功能,就要修改三處地方。

現在我們通過開閉原則對程式碼進行一些修改。把建立Shape類做成抽象類,並提供一個抽象的draw方法,讓子類去實現即可,這樣我們有新的圖形種類時,只需要讓新的圖形類繼承Shape,並實現draw方法即可,使用方的程式碼就不需要修改,滿足了開閉原則

//這是一個用來繪圖的類
public class GraphicEditor {
    //接收Shape物件,然後根據type,來繪製不同的圖形
    public void draw(Shape s) {
       s.draw();
    }

abstract class Shape {
    int m_type;
    public abstract void draw();//抽象方法
}

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

    @Oerride
    public void draw(){
	System.out.println("繪製圓形");
	}
    }

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

    @Oerride
    public void draw(){
	System.out.println("繪製矩形");
	}
    }

// 新繪製三角形
class Triangle extends Shape{
    Triangle() {
	super.m_type = 3;
	}
    @Override
    public void draw() {
	System.out.println("繪製三角形");
	}
    }
}

像這樣假如我們想再擴充套件一個畫菱形畫xxx形,只需要繼承抽象類並重寫抽象方法即可