創(chuàng)建性
1.原型模式——Prototype
2.創(chuàng)建者模式——Builder
3.簡單工廠模式——Simple Factory
結(jié)構(gòu)型
1.適配器模式——Adapter
2.橋接模式——Bridge
3.代理模式——Proxy
行為型
其他設(shè)計模式
生產(chǎn)者消費者模式
控制反轉(zhuǎn)(IoC)依賴注入(DI)
六大原則
1奋渔、單一職責
一個類只做一種類型責任夺英,當這個類需要承當其他類型的責任的時候邢隧,就需要分解這個類。不過在現(xiàn)實開發(fā)中啸臀,這個原則是最不可能遵守的,因為每個人對一個類的哪些功能算是同一類型的職責判斷都不相同玻募。
2览濒、開放封閉原則
對擴展開放,對修改關(guān)閉反肋。
軟件實體應(yīng)該是可擴展那伐,而不可修改的。也就是說石蔗,你寫完一個類罕邀,要想添加功能,不能修改原有類养距,而是想辦法擴展該類诉探。有多種設(shè)計模式可以達到這一要求。
3棍厌、里氏替換原則
所有引用基類(父類)的地方必須能透明地使用其子類的對象肾胯。
當一個子類的實例應(yīng)該能夠替換任何其超類的實例時竖席,它們之間才具有is-A關(guān)系。也就是說接口或父類出現(xiàn)的地方阳液,實現(xiàn)接口的類或子類可以代入怕敬,這主要依賴于多態(tài)和繼承。
4帘皿、接口分離原則
不能強迫用戶去依賴那些他們不使用的接口东跪。換句話說,使用多個專門的接口比使用單一的總接口總要好鹰溜。 不要提供一個大的接口包括所有功能虽填,應(yīng)該根據(jù)功能把這些接口分割,減少依賴曹动。
5斋日、依賴倒置原則
高層模塊不應(yīng)該依賴于低層模塊,二者都應(yīng)該依賴于抽象
抽象不應(yīng)該依賴于細節(jié)墓陈,細節(jié)應(yīng)該依賴于抽象
依賴倒轉(zhuǎn)原則要求我們在程序代碼中傳遞參數(shù)時或在關(guān)聯(lián)關(guān)系中恶守,盡量引用層次高的抽象層類,即使用接口和抽象類進行變量類型聲明贡必、參數(shù)類型聲明兔港、方法返回類型聲明,以及數(shù)據(jù)類型的轉(zhuǎn)換等仔拟,而不要用具體類來做這些事情衫樊。為了確保該原則的應(yīng)用,一個具體類應(yīng)當只實現(xiàn)接口或抽象類中聲明過的方法利花,而不要給出多余的方法科侈,否則將無法調(diào)用到在子類中增加的新方法。
6炒事、迪米特法則
一個軟件實體應(yīng)當盡可能少地與其他實體發(fā)生相互作用臀栈。
補充
依賴倒置原則:
理解幾個點:上層,底層挠乳,抽象权薯,細節(jié)。
舉個例子一般我們會將模塊分為業(yè)務(wù)層欲侮、邏輯層和數(shù)據(jù)層。
業(yè)務(wù)層就是這個模塊要進行的操作肋联,就是要做什么威蕉,邏輯層表示為了業(yè)務(wù)層需要提供的實現(xiàn)方式和細節(jié),數(shù)據(jù)層即為實現(xiàn)業(yè)務(wù)和邏輯所需要的數(shù)據(jù)模型橄仍。
這里業(yè)務(wù)層就是上層韧涨,邏輯和數(shù)據(jù)層是底層牍戚。
抽象和具體就比較好理解,下面的Driveable是抽象虑粥,實現(xiàn)它的就是具體如孝。
public interface Driveable {
void drive();
}
class Bike implements Driveable{
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println("Bike drive.");
}
}
class Car implements Driveable{
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println("Car drive.");
}
}
在開發(fā)中我們是這樣的編碼:
public class Person {
private Bike mBike;
public Person() {
mBike = new Bike();
}
public void out() {
System.out.println("出門了");
mBike.drive();
}
}
創(chuàng)建了一個 Person 類,擁有一臺自行車娩贷,出門的時候就騎自行車第晰。
public class Test1 {
public static void main(String[] args) {
Person person = new Person();
person.out();
}
}
不過,自行車適應(yīng)很短的距離彬祖。如果茁瘦,我要出門逛街呢?自行車就不大合適了储笑。于是就要改成汽車甜熔。
public class Person {
private Bike mBike;
private Car mCar;
public Person() {
//mBike = new Bike();
mCar = new Car();
}
public void out() {
System.out.println("出門了");
//mBike.drive();
mCar.drive();
}
}
我們需要修改 Person 這個類的代碼
不過,如果我要到北京去突倍,那么汽車也不合適了腔稀,還要修改。(違反了開閉原則)
而依賴倒置原則正好適用于解決這類情況羽历。
- 上層模塊不應(yīng)該依賴底層模塊焊虏,它們都應(yīng)該依賴于抽象。
- 抽象不應(yīng)該依賴于細節(jié)窄陡,細節(jié)應(yīng)該依賴于抽象
按照決策能力高低或者重要性劃分炕淮,Person屬于上層模塊,Bike跳夭、Car屬于底層模塊涂圆。
上層Person不應(yīng)該依賴與底層(Bike,Car),應(yīng)該依賴于抽象(Driveable)
public class Person {
// private Bike mBike;
// private Car mCar;
private Driveable mDriveable;
public Person() {
//mBike = new Bike();
mDriveable = new Car(); // 里氏替代
}
public void out() {
System.out.println("出門了");
//mBike.drive();
//mCar.drive();
mDriveable.drive();
}
}
那么币叹,抽象不應(yīng)該依賴于細節(jié)润歉,細節(jié)應(yīng)該依賴于抽象又是什么意思呢?
Driveable 是抽象颈抚,它代表一種行為踩衩,而 Bike、Car 都是實現(xiàn)細節(jié)贩汉。
Person 需要的是 Driveable驱富,需要的是交通工具,但不是說交通工具一定是 Bike匹舞、Car褐鸥。未來也可能是 AirPlane。
本來正常編碼下赐稽,肯定會出現(xiàn)上層依賴底層的情況叫榕,而依賴倒置原則的應(yīng)用則改變了它們之間依賴的關(guān)系浑侥,它引進了抽象。上層依賴于抽象晰绎,底層的實現(xiàn)細節(jié)也依賴于抽象寓落,所以依賴倒置我們可以理解為依賴關(guān)系被改變,如果非常糾結(jié)于倒置這個詞荞下,那么倒置的其實是底層細節(jié)伶选,原本它是被上層依賴,現(xiàn)在它倒要依賴與抽象的接口锄弱。
這里順便提一下依賴注入(DI)考蕾,就拿上面的例子來說,每次改變出行方式都需要Person類会宪,如何避免這種修改呢肖卧,可以使用依賴注入的三種方式(構(gòu)造注入,setter注入和接口注入)來實現(xiàn)掸鹅。
public class Person {
private Driveable mDriveable;
public Person(Driveable mDriveable) {
this.mDriveable = mDriveable;
}
public void out() {
System.out.println("出門了");
mDriveable.drive();
}
}
依賴注入是一種編程思想塞帐,在設(shè)計模式——其他設(shè)計模式 模塊中 控制反轉(zhuǎn)(IoC)依賴注入(DI)一文中詳細介紹。