開閉原則
基本介紹
開閉原則,是編程中最基礎、最重要的設計原則。
一個軟件實體如類,模塊和函數應對外擴展開放(對提供方),對修改關閉(對使用方)。用抽象構建框架,用實現擴展細節。
當軟件需要變化時,儘量通過擴展軟件實體的行爲來實現變化,而不是通過修改已有的代碼來實現變化。
說白了就是增加了新功能,儘量保證以前的使用方代碼不做更改
問題代碼示例
public class Ocp {
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
}
}
/**
* 這是一個用於繪圖的類 [使用方]
*/
class GraphicEditor {
/**
* 接收一個Shape對象,根據Shape的m_type屬性來繪製不同的圖形
*
* @param shape {@link Shape}
*/
public void drawShape(Shape shape) {
if (shape.m_type == 1) {
drawRectangle(shape);
} else if (shape.m_type == 2) {
drawCircle(shape);
}
}
private void drawRectangle(Shape shape) {
System.out.println("繪製矩形");
}
private void drawCircle(Shape shape) {
System.out.println("繪製圓形");
}
}
/**
* Shape類 基類
*/
class Shape {
int m_type;
}
/**
* 矩形類
*/
class Rectangle extends Shape {
public Rectangle() {
super.m_type = 1;
}
}
/**
* 圓形類
*/
class Circle extends Shape {
public Circle() {
super.m_type = 2;
}
}
優點是好理解,簡單易操作。
缺點是違反了設計模式的ocp原則,即對擴展開放(提供方),對修改關閉(對使用方)。即當我們給類增加新功能的時候,儘量不修改代碼或者少修改代碼。
比如我們要給上面增加一個圖形種類(三角形),我們需要再使用方增加一些代碼
修改上面的代碼,採用開閉原則
把創建Shape類做成抽象類,並提供一個draw的方法,讓子類去實現方法即可,這樣我們有新的圖形類的時候,只需要讓圖形類繼承Shape,並實現draw方法即可,使用方的代碼並不需要修改,這樣就滿足了開閉原則。
* 按照開閉原則 優化代碼
*/
public class Ocp {
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.draw(new Rectangle());
graphicEditor.draw(new Triangle());
graphicEditor.draw(new Circle());
}
}
/**
* 繪圖的類,使用方
*/
class GraphicEditor {
public void draw(Shape shape) {
shape.draw();
}
}
/**
* Shape,所有圖形的基類
*/
abstract class Shape {
int m_type;
/**
* 抽象的畫圖方法,需要圖形子類自己去實現
*/
public abstract void draw();
}
/**
* 矩形類
*/
class Rectangle extends Shape {
public Rectangle() {
super.m_type = 1;
}
@Override
public void draw() {
System.out.println("繪製矩形");
}
}
/**
* 圓形類
*/
class Circle extends Shape {
public Circle() {
super.m_type = 2;
}
@Override
public void draw() {
System.out.println("繪製圓形");
}
}
class Triangle extends Shape {
public Triangle() {
super.m_type = 3;
}
@Override
public void draw() {
System.out.println("繪製三角形");
}
}
上面的代碼就算是增加了圖形類,但是使用方GraphicEditor的代碼是不需要進行更改的