android中的用到的設計模式

設計模式

目錄

一 單利模式

用EventBus的建立方式爲例子

public class EventBus {
    private static volatile EventBus defaultInstance;
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }
}
複製代碼

構造方法私有,靜態方法獲得實例 volatile 關鍵字:告訴不一樣的線程 不要拿寄存器的值,要拿主存的值 synchronized 關鍵字:能夠同步與 方法 或者 代碼塊html

優化點

  • 優勢
  1. 提供了對惟一實例的受控訪問;
  2. 因爲在系統內存中只存在一個對象,所以能夠節約系統資源,對於一些須要頻繁建立和銷燬的對象單例模式無疑能夠提升系統的性能;
  3. 能夠根據實際狀況須要,在單例模式的基礎上擴展作出雙例模式,多例模式;
  • 缺點
  1. 單例類的職責太重,裏面的代碼可能會過於複雜,在必定程度上違背了「單一職責原則」。
  2. 若是實例化的對象長時間不被利用,會被系統認爲是垃圾而被回收,這將致使對象狀態的丟失。

二 工廠模式

用汽車爲例子java

1. 先建一個 Car 的抽象類

public abstract class Call{
    // 啓動 開車
    public abstract Start();
}
複製代碼

2. 好比 有 奧迪, 有寶馬...

// 奧迪車類
public AodiCar extends Car{
     public void Start(){
         system.out.println("奧迪車啓動了")
     };
}

// 寶馬車類
public BWMCar extends Car{
     public void Start(){
         system.out.println("寶馬車啓動了")
     };
}
複製代碼

3.建一個工廠生產

public class CarFactory{
   //此處傳遞過來的參數是 包.類名
   public static Car getInstance(Class  clazz) {       
	         
	         Car car = null;
	         
	         try {
	             //利用反射 實例化對象
	             car = (Car)Class.forName(clazz.getName).newInstance();       
	             
	        }catch(Exception e) {
	            
	             e.printStackTrace();
	         }
	         return car;
	     }
}
複製代碼

4. 測試

Car aodiCar= CarFactory.getInstance(AodiCar.class)
Car bmwCar= CarFactory.getInstance(BWMCar.class)
aodiCar.start();
bmwCar.start();
複製代碼

5.場景

好比Retrfit中有不少個Service 你徹底能夠用工廠模式作
複製代碼

三 觀察者模式

場景不少, 好比EventBus , Rxjava 等等

須要知道的東西

  • 抽象被觀察者角色:
    也就是一個抽象主題,它把全部對觀察者對象的引用保存在一個集合中,每一個主題均可以有任意數量的觀察者。抽象主題提供一個接口,能夠增長和刪除觀察者角色。通常用一個抽象類和接口來實現。
  • 抽象觀察者角色:
    爲全部的具體觀察者定義一個接口,在獲得主題通知時更新本身
  • 具體被觀察者角色:
    也就是一個具體的主題,在集體主題的內部狀態改變時,全部登記過的觀察者發出通知
  • 具體觀察者角色:
    實現抽象觀察者角色所須要的更新接口,一邊使自己的狀態與製圖的狀態相協調。

開始寫例子 好比銀行向每一個客戶發送推廣廣告

定義一個抽象被觀察者接口

public interface Observerable{
     // 用來註冊觀察者 也就是註冊用戶
	void register(Observe o); 
    // 移除觀察者   也就是移除用戶
	void unRegister(Observe o) 
    //通知   也就是發送推廣廣告
	void notifyAll();        
}
複製代碼

定義一個抽象觀察者

public interface Observe{
    // 收到消息 也就是收到銀行的廣告通知
	void recivered(String msg);  
}
複製代碼

定義一個抽象被觀察者接口的實現類

public class ObserverableImpl implements ObserveAble{
    // 這個是存貯全部註冊過的觀察者
	private ArrayList<Observe> list;  
    // 記錄要下發的消息 
	private String message;   
	public ObserverableImpl(){
		list = new ArrayList();
	}

    // 添加
	@Override
	public void register(Observe o){  
		if(!list.contains(o)){
			list.add(o);
		}
	}

    //移除
	@Override
	public void unRegister(Observe o){ 
		if(list.contains(o)){
			list.remove(o);
		}
	}
	
     //通知
	@Override
	public void notifyAll(){  
		for(int i=0;i++;i<list.size()){
			list.get(i).recivered(message); // 而後調用 觀察者的方法
		}
	}
	
	// 給外界暴露的方法 設置消息而且通知
	public void setInfomation(String s) {  
		this.message = s;
		//消息更新,通知全部觀察者
		notifyAll();
	}

	
}
複製代碼

具體觀察者實現類

public class  ObserveImpl(){
    private String name;
	public ObserveImpl(String name){
	    this.name=name;
	}
	@Override
	public void recivered(String msg){
		//收到消息 去作本身的事情	
		 System.out.println(name + " 收到推送過來的消息: " + message);
	}
}
複製代碼

測試

// 銀行
   Observerable obserebale = new ObserverableImpl();
   //用戶
   Observer xiaoming = new ObserveImpl("小明");
   Observer xiaohong = new ObserveImpl("小紅");
  obserebale.register(userZhang);
  obserebale.register(userLi);
  // 調用Observerable的發送消息
 obserebale.setInfomation("你中獎100w"); 
複製代碼

打印的日誌是:android

小明收到推送的消息你中獎100w
小紅收到推送的消息你中獎100w
複製代碼

四 建造者模式 (builder模式)

典型的例子 (不少)

  • android 中的dialog(最典型了)
  • okhttp 的 OkHttpClient.BuilderRequest.Builder
  • EventBus 的 EventBusBuilder

例子

public class Person {
    private String mName;
    private int mAge;
    private String mAddress;

    private Person(Builder builder) {
        mName = builder.mName;
        mAge = builder.mAge;
        mAddress = builder.mAddress;
    }


    public static final class Builder {
        private String mName;
        private int mAge;
        private String mAddress;

        public Builder() {
        }

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

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

        public Builder setAddress(String address) {
            mAddress = address;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }
}
複製代碼

使用

Person person = new Person.Builder().setAddress("河北邯鄲").setName("nzy").setAge(27).build();
複製代碼

Studio 插件 能夠一鍵生成builder格式代碼 InnerBuilder 插件

優缺點(參考)

  • 優勢:
    1. 不須要知道產品內部的組成細節,產品與建立過程解耦
    2. 分步組裝產品,使得產品的建立過程更精細更清晰
    3. 容易擴展,新產品只須要新建一個建造者便可
  • 缺點:
    1. Builder模式建立的產品差別性小,使用範圍受限制
    2. 不一樣的產品會產生多個建造者和指揮者

五 動態代理模式

他的特徵是代理類與委託類有一樣的接口,代理類主要負責爲委託類預處理消息、過濾消息、把消息轉發給委託類,以及過後處理消息等。spring

場景:

android中的hook技術,有些插件化技術,spring中經過動態代理實現了aop(切面編程),retrofit.create編程

以retrofit爲例子

須要代理的類(ApiService)

public interface ApiService
	{
		@GET("/heiheihei")
		public void add(int a, int b);

	}
}
複製代碼

代理類

class MyInvocationHandler implements InvocationHandler{

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Integer a = (Integer) args[0];
        Integer b = (Integer) args[1];
        System.out.println("方法名:" + method.getName());
        System.out.println("參數:" + a + " , " + b);
        GET get = method.getAnnotation(GET.class);
        System.out.println("註解:" + get.value());
        return null;
    }
}
複製代碼

開始代理

ApiService service = (ApiService) Proxy.newProxyInstance(ApiService.class.getClassLoader(), new Class<?>[]{ITest.class},new MyInvocationHandler())
複製代碼

六 裝飾着模式

動態地爲一個對象添加一些額外的職責,若要擴展一個對象的功能,裝飾者提供了比繼承更有彈性的替代方案。設計模式

場景: I/o流

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("..")));
複製代碼

構成

  • 抽象構件類(Component):給出一個抽象的接口,用以規範準備接收附加責任的對象
  • 具體構件類(ConcreteComponent):定義一個具體的準備接受附加責任的類,其必須實現Component接口。
  • 裝飾者類(Decorator):持有一個構件(Conponent)對象的實例,並定義一個和抽象構件一致的接口。
  • 具體裝飾者類(Concrete Decoratator):定義給構件對象「貼上」附加責任。

參考文章

相關文章
相關標籤/搜索