常見設計模式總結(一)單例&觀察者&裝飾者
阿新 • • 發佈:2018-12-12
目錄
單例模式
簡單點說,就是一個應用程式中,某個類的例項物件只有一個,你沒有辦法去new,因為構造器是被private修飾的,一般通過getInstance()的方法來獲取它們的例項。getInstance()的返回值是一個物件的引用,並不是一個新的例項,所以不要錯誤的理解成多個物件。 例子:
public class Singleton { private static Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
單例模式的兩種寫法:
懶漢: 是你真正用到的時候才去建這個單例物件 餓漢: 是不管你用的用不上,一開始就建立這個單例物件
// 懶漢式 public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } // 餓漢式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
觀察者模式
物件間一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。 舉個通俗的栗子:
有三個人,小美,老王和老李。小美很漂亮,很風騷,老王和老李是兩個中年男屌絲,時刻關注著小美的一舉一動。
有一天,小美說了一句:我老公今天不在家,一個人好無聊啊~~~,這句話被老王和老李聽到了,結果樂壞了,
蹭蹭蹭,沒一會兒,老王就衝到小美家門口了,於是進門了……~
在這裡,小美是被觀察者,老王和老李是觀察者,被觀察者發出一條資訊,然後觀察者們進行相應的處理。
程式碼如下:
public interface Person { //老王和老李通過這個介面可以接收到小美髮過來的訊息 void getMessage(String s); }
這個介面相當於老王和老李的電話號碼,小美髮送通知的時候就會呼叫getMessage這個介面。
// 這是老王,老李的類似,都實現了Person介面(接收小美的訊息)
public class LaoWang implements Person {
private String name = "老王";
public LaoWang() {}
@Override
public void getMessage(String s) {
System.out.println(name + "接到了小美打過來的電話,電話內容是:" + s);
}
}
// 這是小美
public class XiaoMei {
List<Person> list = new ArrayList<Person>();
public XiaoMei(){
}
public void addPerson(Person person){
list.add(person);
}
//遍歷list,把自己的通知傳送給所有暗戀自己的人
public void notifyPerson() {
for(Person person:list){
person.getMessage("今天家裡就我一個人,你們過來吧,先到先得!");
}
}
}
我們寫一個測試類來看一下結果
public class Test {
public static void main(String[] args) {
XiaoMei xiao_mei = new XiaoMei();
LaoWang lao_wang = new LaoWang();
LaoLi lao_li = new LaoLi();
//老王和老李在小美那裡都註冊了一下
xiao_mei.addPerson(lao_wang);
xiao_mei.addPerson(lao_li);
//小美向老王和老李傳送通知
xiao_mei.notifyPerson();
}
}
執行結果:
老王接到了小美打過來的電話,電話內容是:今天家裡就我一個人,你們過來吧,先到先得!
老李接到了小美打過來的電話,電話內容是:今天家裡就我一個人,你們過來吧,先到先得!
裝飾者模式
對已有的業務邏輯進一步的封裝,使其增加額外的功能。 如Java中的IO流就使用了裝飾者模式,使用者在使用的時候,可以任意組裝,達到自己想要的效果。 舉個栗子,我想吃三明治,首先我需要一根大大的香腸,我喜歡吃奶油,在香腸上面加一點奶油,再放一點蔬菜,最後再用兩片面包夾一下,營養又健康。
那我們應該怎麼來寫程式碼呢? 首先,我們需要寫一個Food類,讓其他所有食物都來繼承這個類 食物類:
public class Food {
private String foodName;
public Food(){}
public Food(String foodName){
this.foodName = foodName;
}
public String make(){
return foodName;
}
}
麵包類:
public class Bread extends Food {
private Food basicFood;
public Bread(Food basicFood) {
this.basicFood = basicFood;
}
public String make() {
return basicFood.make() + "+麵包";
}
}
奶油類:
public class Cream extends Food {
private Food basicFood;
public Cream(Food basicFood) {
this.basicFood = basicFood;
}
public String make() {
return basicFood.make() + "+奶油";
}
}
這幾個類都是差不多的,構造方法傳入一個Food型別的引數,然後在make方法中加入一些自己的邏輯
public class Test {
public static void main(String[] args) {
Food food = new Bread(new Cream(new Food("5元肉夾饃")));
System.out.println(food.make());
}
}
執行結果:
5元肉夾饃+奶油+麵包