【設計模式】七大設計原則(三)—— 開閉原則(Open Close Principle)
阿新 • • 發佈:2022-04-20
開閉原則描述
-
開閉原則是程式設計中最基礎、最重要的原則
-
一個軟體實體如類,模組和函式應該對擴充套件開發(對提供方),對修改關閉(對使用方)。用抽象構成框架,用實現擴充套件細節。
-
當軟體需要變化時,儘量通過擴充套件軟體實體的行為來實現變化,而不是通過修改已有程式碼來實現變化。
-
程式設計中遵循其他原則,以及使用設計模式的目的就是遵循開閉原則。
示例分析
需求: 有圓形, 有橢圓形, 根據要求畫出相應的形狀
//這是一個用來繪圖的類 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形,只需要繼承抽象類並重寫抽象方法即可