1. 程式人生 > >Android常用設計模式

Android常用設計模式

 

目錄

單例模式:

餓漢式:

懶漢式:

雙重校驗鎖(DCL):

靜態內部類:

建造者模式(Builder模式):

觀察者模式:

策略模式


在Android中常用的設計模式有:單例模式,工廠模式,觀察者模式等,下面根據具體案例深刻了解模式具體的表現:

單例模式:

單例模式存在的意義主要就是保證有且僅有一個物件,只建立一個,所有想要拿到該單例的都是同一個物件。

優點:

1).由於單例模式在記憶體中只有一個例項,減少了記憶體開銷。對於那些耗記憶體的類,只例項化一次,大大提高效能,尤其是移動開發中。

2).單例模式可以避免對資源的多重佔用,例如一個寫檔案時,由於只有一個例項存在記憶體中,避免對同一個資原始檔的同時寫操作。

3).單例模式可以在系統設定全域性的訪問點,優化和共享資源訪問。

餓漢式:

public class EHanSingleton {
    //在類初始化時,已經自行例項化,所以是執行緒安全的。
    private static final EHanSingleton single =new EHanSingleton();

    public static EHanSingleton getInstance(){
        return single;
    }
}
  • 優點:寫法簡單,執行緒安全。
  • 缺點:沒有懶載入的效果,如果沒有使用過的話會造成記憶體浪費。

懶漢式:

public class LanHanSingleton {
    private static LanHanSingleton singleton;

    public static synchronized LanHanSingleton getSingleton(){
        if (singleton == null){
            singleton =new LanHanSingleton();
        }
        return singleton;
    }
}
  • 優點:實現了懶載入的效果,執行緒安全。
  • 缺點:使用synchronized會造成不必要的同步開銷,而且大部分時候我們是用不到同步的。

雙重校驗鎖(DCL):

public class DoubleCheckSingleton {
    private volatile static DoubleCheckSingleton singleton;

    public static DoubleCheckSingleton getInstance(){
        if (singleton == null){
            synchronized (DoubleCheckSingleton.class){
                if (singleton == null){
                    singleton =new DoubleCheckSingleton();
                }
            }
        }
        return singleton;
    }
}
  • 優點:懶載入,執行緒安全,效率較高
  • 缺點:volatile影響一點效能,高併發下有一定的缺陷,某些情況下DCL會失效,雖然概率較小

靜態內部類:

public class StaticInnerSigleton {

    public static StaticInnerSigleton getInstance(){
        return StaticInner.single;
    }

    //靜態內部類
    private static class StaticInner{
        private static final StaticInnerSigleton single =new StaticInnerSigleton();
    }
}
  • 優點:懶載入,執行緒安全,推薦使用

建造者模式(Builder模式):

定義:將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

public class UserInfo {

    private String name;
    private int age;
    private double height;
    private double weight;

    private UserInfo(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.height = builder.height;
        this.weight = builder.weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    static class Builder {
        private String name;
        private int age;
        private double height;
        private double weight;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Builder height(double height) {
            this.height = height;
            return this;
        }

        public Builder weight(double weight) {
            this.weight = weight;
            return this;
        }

        public UserInfo build() {
            return new UserInfo(this);
        }
    }
}

 

//建立
UserInfo.Builder builder=new UserInfo.Builder();
        UserInfo person=builder
                .name("張三")
                .age(18)
                .height(178.5)
                .weight(67.4)
                .build();

//獲取UserInfo的屬性
Log.e("userinfo","name = "+person.getName());

Android中很多地方運用了Builder模式,比如常見的對話方塊建立/Okhttp等


AlertDialog.Builder builder=new AlertDialog.Builder(this);  
AlertDialog dialog=builder.setTitle("對話方塊")  
        .setIcon(android.R.drawable.ic_dialog)  
        .setView(R.layout.custom_view)  
        .setPositiveButton(R.string.positive, new DialogInterface.OnClickListener() {  
            @Override  
            public void onClick(DialogInterface dialog, int which) {  
  
            }  
        })  
        .setNegativeButton(R.string.negative, new DialogInterface.OnClickListener() {  
            @Override  
            public void onClick(DialogInterface dialog, int which) {  
  
            }  
        })  
        .create();  
dialog.show();

Request.Builder builder=new Request.Builder();  
Request request=builder.addHeader("","")  
    .url("")  
    .post(body)  

觀察者模式:

定義:物件間一種一對多的依賴關係,使得當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。

運用的場景:廣播,EventBus等都是觀察者模式

主要包括四個部分:
  1. Subject被觀察者。是一個介面或者是抽象類,定義被觀察者必須實現的職責,它必須能偶動態地增加、取消觀察者,管理觀察者並通知觀察者。
  2. Observer觀察者。觀察者接收到訊息後,即進行update更新操作,對接收到的資訊進行處理。
  3. ConcreteSubject具體的被觀察者。定義被觀察者自己的業務邏輯,同時定義對哪些事件進行通知。
  4. ConcreteObserver具體觀察者。每個觀察者在接收到資訊後處理的方式不同,各個觀察者有自己的處理邏輯。

模擬場景:天氣預報,每次天氣更新都會向你及時傳送訊息,觀察者們就要更新介面。寫法如下:

public class Weather {  

    private String description;  
  
    public Weather(String description) {  
        this.description = description;  
    }  
  
    public String getDescription() {  
        return description;  
    }  
  
    public void setDescription(String description) {  
        this.description = description;  
    }  
  
    @Override  
    public String toString() {  
        return "Weather{" +  
                "description='" + description + '\'' +  
                '}';  
    }  
}  

 

然後定義我們的被觀察著,我們希望它能夠通用,所以定義成泛型,內部應該暴露出register和unRegister供觀察者訂閱和取消訂閱,至於觀察者的儲存,我們用ArrayList即可,另外,當主題發生變化的時候,需要通知觀察者來做出響應,還需要一個notifyObservers方法,具體實現如下:

public class Observable<T> {  
    List<Observer<T>> mObservers = new ArrayList<Observer<T>>();  
  
    public void register(Observer<T> observer) {  
        if (observer == null) {  
            throw new NullPointerException("observer == null");  
        }  
        synchronized (this) {  
            if (!mObservers.contains(observer))  
                mObservers.add(observer);  
        }  
    }  
  
    public synchronized void unregister(Observer<T> observer) {  
        mObservers.remove(observer);  
    }  
  
    public void notifyObservers(T data) {  
        for (Observer<T> observer : mObservers) {  
            observer.onUpdate(this, data);  
        }  
    }  
  
}  

而我們的觀察者只需要實現一個觀察者的介面Observer,該介面也是泛型的

public interface Observer<T> {  
    void onUpdate(Observable<T> observable,T data);  
}  

呼叫:

public class Main {  
    public static void main(String [] args){  
        Observable<Weather> observable=new Observable<Weather>();  
        Observer<Weather> observer1=new Observer<Weather>() {  
            @Override  
            public void onUpdate(Observable<Weather> observable, Weather data) {  
                System.out.println("觀察者1:"+data.toString());  
            }  
        };  
        Observer<Weather> observer2=new Observer<Weather>() {  
            @Override  
            public void onUpdate(Observable<Weather> observable, Weather data) {  
                System.out.println("觀察者2:"+data.toString());  
            }  
        };  
  
        observable.register(observer1);  
        observable.register(observer2);  
  
  
        Weather weather=new Weather("晴轉多雲");  
        observable.notifyObservers(weather);  
  
        Weather weather1=new Weather("多雲轉陰");  
        observable.notifyObservers(weather1);  
  
        observable.unregister(observer1);  
  
        Weather weather2=new Weather("颱風");  
        observable.notifyObservers(weather2);  
  
    }  
}  

策略模式: