
1.定義
1.一個軟件實體如類、模塊和函數(shù)應該對擴展開放,對修改關閉。
對組建的功能擴展是開放的,對原有代碼的修改是封閉的
是面向?qū)ο笤O計的核心,是最基礎的一個原則,其他五種設計原則都是針對于開閉原則的實現(xiàn)方式和方法
2.作用
- 可復用性
- 可維護性
3.案例
以LOL 選英雄為例子,提供英雄英雄,符文,天賦三個屬性,具體的實現(xiàn)類CommonRole
/**
* 角色
*/
public interface IRole {
//英雄
String getHero();
//符文
String getFuWen();
//天賦
String getGenius();
}
public class CommonRole implements IRole {
//英雄
private String hero;
//符文
private String fuWen;
//天賦
private String genius;
public CommonRole(String hero, String fuWen, String genius) {
this.hero = hero;
this.fuWen = fuWen;
this.genius = genius;
}
@Override
public String getHero() {
return hero;
}
@Override
public String getFuWen() {
return fuWen;
}
@Override
public String getGenius() {
return genius;
}
}
寫一個Main函數(shù)打印其內(nèi)容
public class Main {
public static void main(String[] args) {
List<IRole> role = new ArrayList<>();
role.add(new CommonRole("蓋倫","全肉符文","全肉天賦"));
System.out.println("英雄:"+role.get(0).getHero());
System.out.println("符文:"+role.get(0).getFuWen());
System.out.println("天賦:"+role.get(0).getGenius());
}
}
打印結果如下:
英雄:蓋倫
符文:全肉符文
天賦:全肉天賦
隨著項目的發(fā)展,在選擇角色的這個環(huán)節(jié)增加了皮膚這個選項,那么本著開閉原則不可能在原有的接口中增加皮膚這個選擇,如果在原有的接口上增加,不僅要修改接口,實現(xiàn)類,業(yè)務邏輯也要發(fā)生變化,最好的方式是對組建功能進行擴展,修改如下:
public interface ISkinRole extends IRole{
//皮膚
String getSkin();
}
在原有基礎上增加ISkin接口,對應的實現(xiàn)類Skin
public class SkinRole implements ISkinRole {
//英雄
private String hero;
//符文
private String fuWen;
//天賦
private String genius;
//皮膚
private String skin;
public SkinRole(String hero, String fuWen, String genius, String skin) {
this.hero = hero;
this.fuWen = fuWen;
this.genius = genius;
this.skin = skin;
}
@Override
public String getSkin() {
return skin;
}
@Override
public String getHero() {
return hero;
}
@Override
public String getFuWen() {
return fuWen;
}
@Override
public String getGenius() {
return genius;
}
}
在main函數(shù)中新增加一條數(shù)據(jù)
public static void main(String[] args) {
List<IRole> role = new ArrayList<>();
role.add(new CommonRole("蓋倫","全肉符文","全肉天賦"));
role.add(new SkinRole("劍圣","攻擊符文","攻擊天賦","天人合一皮膚"));
System.out.println("英雄:"+role.get(0).getHero() +" 符文:"+role.get(0).getFuWen()+" 天賦:"+role.get(0).getGenius());
System.out.println("英雄:"+role.get(1).getHero() +" 符文:"+role.get(1).getFuWen()+" 天賦:"+role.get(1).getGenius());
}
打印結果如下:
英雄:蓋倫 符文:全肉符文 天賦:全肉天賦
英雄:劍圣 符文:攻擊符文 天賦:攻擊天賦
OK!在沒有修改其他業(yè)務就實現(xiàn)了對皮膚功能的擴展,完成了業(yè)務的變化。
4.總結
抽象層盡量保持穩(wěn)定,一旦確定就不要修改,參數(shù)類型、引用對象盡量使用接口或者抽象類,而不是實現(xiàn)類。掌握并運用好設計模式,將輕松的適應不同的變化。