前言
我們已經學習了單一職責原則,依賴倒置原則,介面隔離原則,李氏替換原則。可以說前面幾個原則都是為了開閉原則奠定基礎。
我們寫的程式由於實際的情況可以一定程度上違背各種設計原則。但是,開閉原則我認為作為一個程式猿無論什麼時候都需要遵循他,切記不可違揹她。
基本介紹
- 開閉原則(Open Closed Principle)是程式設計中最基礎、最重要的設計原則
- 一個軟體實體如類,模組和函式應該對擴充套件開放(對提供方),對修改關閉(對使用方)。用抽象構建框架,用實現擴充套件細節。
- 當軟體需要變化時,儘量通過擴充套件軟體實體的行為來實現變化,而不是通過修改已 有的程式碼來實現變化。
- 程式設計中遵循其它原則,以及使用設計模式的目的就是遵循開閉原則
那麼翻譯成通俗的話就是:
對修改關閉,對擴充套件開放。舉個例子,當我們要新增功能的時候,我們希望的是不修改的原有的程式碼。而是對程式碼進行一種擴充套件。後續我們用程式碼示例。
這個原則更像是前四個原則甚至是所有原則的總綱,只要我們儘量的遵守其他的設計原則,那麼設計出來的系統應該就比較符合開閉原則了,相反,如果你違背了太多,那麼你的系統或許也不太遵循開閉原則。
案例
我們先來看一個反例
public class test {
public static void main(String[] args) {
Paintbrush graphicEditor = new Paintbrush();
Shape rectangle = new Rectangle();
Shape circle = new Circle();
graphicEditor.drawShape(rectangle);
graphicEditor.drawShape(circle);
}
}
class Paintbrush {
public void drawShape(Shape s) {
if (s.m_type == 1)
drawRectangle(s);
else if (s.m_type == 2)
drawCircle(s);
}
private void drawRectangle(Shape r) {
System.out.println(" 矩形 ");
}
private void drawCircle(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類做成抽象類,並提供一個抽象的draw方法,讓子類去實現即可, 這樣我們有新的圖形種類時,只需要讓新的圖形類繼承Shape,並實現draw方法即可, 使用方的程式碼就不需要修 -> 滿足了開閉原則
public class test {
public static void main(String[] args) {
Paintbrush graphicEditor = new Paintbrush();
Shape rectangle = new Rectangle();
Shape circle = new Circle();
Shape triangle = new Triangle();
Shape otherGraphic = new OtherGraphic();
graphicEditor.drawShape(rectangle);
graphicEditor.drawShape(circle);
graphicEditor.drawShape(triangle);
graphicEditor.drawShape(otherGraphic);
}
}
class Paintbrush {
public void drawShape(Shape s) {
s.draw();
}
}
abstract class Shape {
int m_type;
public abstract void draw();
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
@Override
public void draw() {
System.out.println(" 矩形 ");
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
@Override
public void draw() {
System.out.println(" 圓形 ");
}
}
class Triangle extends Shape {
Triangle() {
super.m_type = 3;
}
@Override
public void draw() {
System.out.println(" 三角形");
}
}
class OtherGraphic extends Shape {
OtherGraphic() {
super.m_type = 4;
}
@Override
public void draw() {
System.out.println(" 其他圖形");
}
}
通過這樣的修改,我們以後每次新增一個圖形不需要再做任何的修改,只需要new一個我們需要的圖形,繼承Shape類,實現繪畫方法即可。
希望大家細細體會,什麼是對修改關閉,對修改關閉,對擴充套件開放
總結
開閉原則是我們程式碼實現中最最基礎,最最重要的原則。看一個人的程式碼功底是否優秀,你就可以看他寫的程式碼是否是遵循這個原則的。如果連這個原則都不遵循的程式碼,我相信,後期的維護你自己都會罵娘。