1. 輸入法皮膚擴展(抽象類實現)
場景:用戶可為輸入法更換不同皮膚(如默認皮膚、CSDN皮膚)。
實現:
- 抽象層:定義抽象類
AbstractSkin
,聲明皮膚顯示方法。 - 擴展:新增皮膚只需繼承抽象類并實現方法,無需修改輸入法主類。
// 抽象皮膚類
public abstract class AbstractSkin {public abstract void display();
}
// 具體皮膚類
public class DefaultSkin extends AbstractSkin {@Overridepublic void display() { System.out.println("默認皮膚"); }
}
public class CSDNSkin extends AbstractSkin {@Overridepublic void display() { System.out.println("CSDN皮膚"); }
}
// 輸入法類(依賴抽象)
public class SouGouInput {private AbstractSkin skin;public void setSkin(AbstractSkin skin) { this.skin = skin; }public void display() { skin.display(); }
}
擴展性:新增TheodoreSkin
時,僅需編寫新子類,調用setSkin()
即可生效。
2. 圖形繪制系統(多態替代條件判斷)
問題:原始代碼通過if-else
判斷圖形類型,新增圖形需修改核心邏輯(違反OCP)。
// 違反OCP的原始代碼
class GraphicEditor {void drawShape(Shape s) {if (s.m_type == 1) drawRectangle(s);else if (s.m_type == 2) drawCircle(s);}
}
改進:抽象類Shape
定義draw()
方法,子類實現具體邏輯。
// 遵循OCP的改進代碼
abstract class Shape { abstract void draw(); }
class Rectangle extends Shape { @Override void draw() { System.out.println("繪制矩形"); }
}
class Triangle extends Shape { @Override void draw() { System.out.println("繪制三角形"); }
}
// 調用方無需修改
class GraphicEditor { void drawShape(Shape s) { s.draw(); }
}
優勢:新增圖形只需添加子類,無需改動GraphicEditor
。
3. 支付方式擴展(策略模式)
場景:支持微信、支付寶等支付方式,新增支付方式時無需修改核心邏輯。
實現:
- 接口定義:聲明支付行為。
- 擴展:新增支付類實現接口,通過工廠動態創建。
// 支付接口
public interface Payment {void pay();
}
// 具體支付類
public class WeChatPay implements Payment {@Override public void pay() { System.out.println("微信支付"); }
}
// 支付工廠(擴展時新增工廠方法)
public class PaymentFactory {public static Payment create(String type) {if ("wechat".equals(type)) return new WeChatPay();// 擴展支付寶:新增條件分支else if ("alipay".equals(type)) return new AliPay();return null;}
}
擴展性:新增AliPay
類后,僅需擴展工廠邏輯,調用方代碼不變。
4. 動物行為擴展(接口隔離)
場景:統一管理不同動物的共同行為(如eat()
),擴展行為時不影響原有邏輯。
// 動物接口
public interface Animal {void eat();
}
// 具體動物類
public class Cat implements Animal {@Override public void eat() { System.out.println("貓吃魚"); }// 新增行為(如sleep()):僅擴展當前類,不影響其他動物public void sleep() { System.out.println("貓睡覺"); }
}
說明:新增行為通過擴展具體類實現,接口保持穩定。
5. 圖形面積計算(從硬編碼到抽象)
問題:原始代碼通過instanceof
判斷圖形類型,新增圖形需修改計算邏輯。
// 違反OCP的原始代碼
double calculateArea(Object shape) {if (shape instanceof Circle) { /* 計算圓面積 */ }else if (shape instanceof Rectangle) { /* 計算矩形面積 */ }
}
改進:定義Shape
接口,子類實現計算邏輯。
// 遵循OCP的改進代碼
interface Shape { double calculateArea(); }
class Circle implements Shape { @Override double calculateArea() { return Math.PI * radius * radius; }
}
擴展性:新增Triangle
類實現接口,計算邏輯無需修改主類。
總結:開閉原則的核心實踐
- 抽象化:通過接口或抽象類定義穩定框架。
- 多態擴展:新增功能通過實現子類完成。
- 設計模式結合:工廠、策略模式等增強擴展性。
- 降低耦合:調用方依賴抽象而非具體實現。
通過上述案例可見,開閉原則顯著提升了代碼的可維護性和擴展性,是構建靈活系統的基礎。