概念
設計模式Design pattern
,是軟件開發(fā)人員在開發(fā)過程中面臨的一般問題的解決方案惠桃,這些方案是經(jīng)過相當長的一段時間的的使用和修改總結(jié)而出。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解辜羊。設計模式是軟件工程的結(jié)構(gòu)。
四大要素
模式名稱(Name)?? 問題(Question)
解決方案(Solution) 效果(Efftive)
三大類型
設計模式分為三種類型:
創(chuàng)建型模式:單例模式词顾,抽象工廠模式八秃,建造者模式等。
結(jié)構(gòu)型模式:適配器模式肉盹,橋接模式昔驱,裝飾模式,組合模式等上忍。
行為型模式:觀察者模式骤肛,中介者模式,訪問者模式窍蓝,解釋器模式腋颠,迭代器模式,備忘錄模式等吓笙。
Android中的重要設計模式
單例模式
概念:保證一個類僅有一個實例淑玫,并提供一個訪問它的全局訪問點。
優(yōu)點:1、對于那些比較耗內(nèi)存的類絮蒿,只實例化一次可以大大提高性能尊搬。
??????2、保持程序運行的時候該中始終只有一個實例存在內(nèi)存中土涝。
常見單例方法:
public class Singleton {
private static volatile Singleton instance = null;
private Singleton(){
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
建造者模式(Builder模式)
概念:將一個復雜對象的構(gòu)建與它的表示分離佛寿,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
優(yōu)點:對于多參數(shù)類但壮,使用重疊構(gòu)造器冀泻,會有難讀、難寫茵肃、難維護的缺點腔长;而直接使用javaBean,又難維護验残、難以保持參數(shù)一致性捞附,特別是多線程的模式下,出bug難以找到原因您没。builder模式正好解決這一問題鸟召,支持鏈式調(diào)用,提高代碼可讀性氨鹏。
常見Builder:
public class UserInfo {
private String name;
private String mail;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
//兩個不同參數(shù)的構(gòu)造方法
public UserInfo(String name) {
this.name = name;
}
public UserInfo(String name, String mail) {
this.name = name;
this.mail = mail;
}
//Bulider 的常見使用
public static class UserBuilder {
private String name;
private String mail;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder mail(String mail) {
this.mail = mail;
return this;
}
}
}
上述代碼中欧募,如果直接使用構(gòu)造方法實例化UserInfo。 我們可能會寫如下代碼:
UserInfo userInfoOne = new UserInfo("張三","999@qq.com");
UserInfo userInfoTwo = new UserInfo("李四");
UserInfo userInfoThree = new UserInfo();
userInfoThree.setName("王五");
userInfoThree.setMail("777@q.com");
如果使用bulider實例化:
UserInfo .Builder builder=new UserInfo.Builder();
UserInfo userInfo=builder
.name("張三")
.mail("666@qq.com")
.build();
觀察者模式(發(fā)布/訂閱模式)
概念:定義對象間的一種一對多的依賴關系仆抵,當一個對象的狀態(tài)發(fā)送改變時跟继,所有依賴于它的對象都能得到通知并被自動更新
優(yōu)點:觀察者模式解除了主題和具體觀察者的耦合,讓耦合的雙方都依賴于抽象镣丑,而不是依賴具體舔糖。從而使得各自的變化都不會影響另一邊的變化。
觀察者莺匠,我們稱它為Observer金吗,有時候我們也稱它為訂閱者,即Subscriber趣竣。
被觀察者摇庙,我們稱它為Observable,即可以被觀察的東西遥缕,有時候還會稱之為主題卫袒,即Subject。
假定一種情況单匣,有無數(shù)個購房者需要買同一套房子夕凝,他們需要知道房子的價格變化烤蜕。對于這種情況,我們嘗試使用觀察者模式來解決迹冤。
//Observable 觀察者
import java.util.Observable;
public class Price extends Observable {
private int price;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
setChanged();
notifyObservers();
}
@Override
public String toString() {
return "房價 [price=" + price + "]";
}
}
//Observable被觀察者
import java.util.Observable;
import java.util.Observer;
public class Buyer implements Observer {
private int id;
private Price price;
public Buyer(int id) {
System.out.println("我是購房者---->" + id);
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Price getPrice() {
return price;
}
@Override
public void update(Observable observable, Object data) {
System.out.println("購房者---->" + id + "得到更新");
this.price = (Price) observable;
System.out.println("價格---->" + observable.toString());
}
}
觀察者和被觀察者構(gòu)建好之后,在使用時虎忌,我們需要將使用addObserver()
deleteObserver()
來綁定和解除綁定泡徙。而在開發(fā)過程中,我們會對其進行接口封裝膜蠢,使用register
和unregister
堪藐。
適配器模式
概念: 適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作挑围。
優(yōu)點:1礁竞、更好的復用性 系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)
?????????的需要杉辙。那么通過適配器模式就可以讓這些功能得到更好的復
?????????用模捂。
??????2、更好的擴展性,在實現(xiàn)適配器功能的時候,可以調(diào)用自己開發(fā)的功
?????????能浅碾,從而自然地擴展系統(tǒng)的功能亚侠。
- 目標(Target)角色:這就是所期待得到的接口。
- 源(Adapee)角色:現(xiàn)在需要適配的接口癌蚁。
- 適配器(Adaper)角色:適配器類是本模式的核心。適配器把源接口轉(zhuǎn)換成目標接口。顯然泡垃,這一角色不可以是接口,而必須是具體類羡鸥。
public interface Target {
public void sampleOperation1();
public void sampleOperation2();
}
public class Adaptee {
public void sampleOperation1(){}
}
類的適配器模式
類的適配器模式把適配的類的API轉(zhuǎn)換成為目標類的API蔑穴。
public class Adapter extends Adaptee implements Target {
@Override
public void sampleOperation2() {
//寫相關的代碼
}
}
對象的適配器模式
與類的適配器模式一樣,對象的適配器模式把被適配的類的API轉(zhuǎn)換成為目標類的API兄春,與類的適配器模式不同的是澎剥,對象的適配器模式不是使用繼承關系連接到Adaptee類,而是使用委派關系連接到Adaptee類赶舆。
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
public void sampleOperation1(){
this.adaptee.sampleOperation1();
}
public void sampleOperation2(){
//寫相關的代碼
}
}
命令模式
概念: 將一個請求封裝成一個對象哑姚,從而使你可用不同的請求對客戶進行參數(shù)化,對請求排隊或記錄請求日志芜茵,以及支持可撤銷的操作叙量。
優(yōu)點: 1、比較容易地實現(xiàn)一個命令隊列九串。
???????2绞佩、比較容易將隊列記入日志寺鸥。
???????3、請求者和實現(xiàn)者通過接口進一步解耦品山。
???????4胆建、可以容易地實現(xiàn)對請求的撤銷和恢復。
???????5肘交、加入新的命令不影響其它類的操作笆载。
- 客戶角色(Client):Client可以創(chuàng)建具體的命令對象,并且設置命令對象的接收者涯呻。Tips:不能把Clinet理解為我們平常說的客戶端凉驻,這里的Client是一個組裝命令對象和接受者對象的角色,或者你把它理解為一個裝配者复罐。
- 調(diào)用者角色(Invoker):負責調(diào)用命令對象執(zhí)行請求涝登,通常會持有命令對象(可以持有多個命令對象)。Invoker是Client真正觸發(fā)命令并要求命令執(zhí)行相應操作的地方(使用命令對象的入口)效诅。
- 命令角色(Command):定義命令的接口胀滚,聲明具體命令類需要執(zhí)行的方法。這是一個抽象角色填帽。
- 具體命令角色(ConcreteCommand):命令接口的具體實現(xiàn)對象蛛淋,通常會持有接收者,并調(diào)用接收者的功能來完成命令要執(zhí)行的操作篡腌。
- 接收者角色(Receiver):Receiver是真正執(zhí)行命令的對象褐荷。任何類都可能成為一個接收者,只要它能夠?qū)崿F(xiàn)命令要求實現(xiàn)的相應功能嘹悼。
//接收者角色類
public class Receiver {
public void action() {
//TODO something
}
}
//抽象命令角色類
public interface Command {
void execute();
}
//具體命令角色類
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.action();
}
}
//請求者角色類
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action() {
command.execute();
}
}
//客戶端
public class Client {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker(command);
invoker.action();
}
}
總結(jié)
設計模式并不神秘叛甫,我們在每天的開發(fā)中都會不經(jīng)意的使用它,去學習它杨伙、了解它其监,能夠更好的幫助我們開發(fā)。有意地接觸這方面的知識限匣,比如高內(nèi)聚抖苦、低耦合、封裝變化米死,在設計接口的時候都是非常重要的原則锌历。如有不足之處,希望多多指出峦筒。