1.單一職責(zé)
- 每一個類,都只有一個引起它變化的原因。即職責(zé)單一。
舉例:
一個用戶的用戶名和密碼,以及對用戶的操作如下:
這樣一個耦合度低的接口,用戶的屬性和用戶的行為沒有分開,即職責(zé)不單一。應(yīng)該分為用戶的屬性(業(yè)務(wù)對象)和用戶的行為(業(yè)務(wù)邏輯)。即為下圖
分為UserBo(管理用戶屬性)和UserBL(管理用戶邏輯)。
然后讓類去實現(xiàn)這兩個接口即可。
這里提出一個概念,即接口職責(zé)單一,因為類職責(zé)單一的話,會造成過度耦合和類文件變多等工程項目的復(fù)雜度問題。
單一職責(zé)原則,很容易被各種因素去忽略,但是這是基本素養(yǎng)也是編程經(jīng)驗,推薦單一職責(zé)接口,而不要建立過多的類去死守此原則。
2.開閉原則
- 一個類對于繼承是開放的,對于修改是封閉的。
對于新功能,應(yīng)該盡量通過擴(kuò)展的方式來實現(xiàn)變化,而不是通過修改已有代碼。OCP原則并不是不能修改原始類的代碼,當(dāng)我們需要重構(gòu)的時候,應(yīng)該盡早地重構(gòu),讓代碼回到進(jìn)化的正軌上。
這時候就要衡量 修改原來的代碼和繼承實現(xiàn)新的功能 哪個更加合適。
3.里氏替換原則
-
定義:所有引用基類的地方必須能透明地使用其子類的對象。
即:子類不能重寫或重載基類的方法。建立規(guī)范時使用基類,具體使用時使用具體的子類。
例如:
顯示在屏幕上,可能顯示按鈕和文本,于是抽象出View,使用show(View v),定義時使用基類進(jìn)行定義,使用時使用show(Button b)或者show(Text t)進(jìn)行使用,這樣就保證了很好的擴(kuò)展性。
4.依賴倒置原則
-
高層模塊不應(yīng)該依賴底層模塊,都依賴于抽象。
依賴注入:即聲明時使用接口或者抽象類,然后將依賴作為一個方法注入進(jìn)去,這樣大大提高了擴(kuò)展性,將來需要修改的時候直接將依賴注入進(jìn)去即可。
5.接口隔離規(guī)則
- 類間的依賴關(guān)系應(yīng)該建立在最小的接口上。
代碼
public void file(){
FileOutputStream f=null;
……
if(f!=null){
try{
f.close();
}catch(IOExeption e){
e.printStackTrace();
}
}
}
這里的關(guān)閉代碼太過丑陋,而且這里只是使用該類的關(guān)閉功能,所以建立一個工具類
public final class CloseUtils {
public static void closeNow(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
原代碼變成
public void file(){
FileOutputStream f=null;
……
CloseUtils.closeNow(f);
}
這里不僅使用了依賴倒置,而且依賴關(guān)系由原來的FileOutputStream類轉(zhuǎn)為最小關(guān)系接口——關(guān)閉接口Closeable類,它只需要知道這個對象是可關(guān)閉的,其他一概不用關(guān)心。
6.迪米特原則
-
也叫最少知識原則,即朋友只跟自己的朋友通信。
比如:
房間Room,中介者M(jìn)ediator,租房者Tenant。
這樣子耦合度太高,所有類之間都有依賴。所以需要解耦,以此例,租房者只與中介者有關(guān),中介者之與房間有關(guān)。
- 內(nèi)部不能依賴其他類,盡量都使用朋友類進(jìn)行操作。朋友類即方法輸入的對象。代碼舉例:
public class Teacher{
public void command(GroupLeader groupLeader){
List<Girl> listGirl=new ArrayList<Girl>();
for(int i=0;i<10;i++){
listGirl.add(new Girl());
}
groupLeader.countGirls(listGirl);
}
}
這個方法里居然依賴了Girl類?這絕對是不允許的?。?!
應(yīng)該修改如下:
public class Teacher{
public void command(GroupLeader groupLeader){
groupLeader.countGirls();
}
}
public class GroupLeader{
private List<Girl> listGirl;
public GroupLeader(List<Girl> _listGirl){
this.listGirl=_listGirl;
}
public void countGirls(){
System.out.println(listGirl.size());
}
}





