編輯:關於Android編程
工作內容:
1.觀察者模式
2.Builder模式
3.單例模式
4.簡單工廠模式
學習分享:
一、觀察者模式【代碼參考例1】
在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。[觀察者和被觀察者之間存在“觀察”的邏輯關聯,當被觀察者發生改變的時候,觀察者就會觀察到這樣的變化,並且做出相應的響應。]
觀察者:(Observer)將自己注冊到被觀察對象(Subject)中,被觀察對象將觀察者存放在一個容器(Container)裡。
被觀察:被觀察對象發生了某種變化(如圖中的SomeChange),從容器中得到所有注冊過的觀察者,將變化通知觀察者。
二、Builder模式【代碼參考例2】
(1) 意圖:將一個“復雜對象的構建算法”與它的“部件及組裝方式”分離,使得構件算法和組裝方式可以獨立應對變化;復用同樣的構建算法可以創建不同的表示,不同的構建過程可以復用相同的部件組裝方式。
(2) 適用性:
當同時滿足以下情況的時候可以使用Builder模式
a. 當創建復雜對象的算法應該獨立於該對象的組成部分以及他們的裝配方式;
b. 當構造過程必須允許構造的對象有不同的表示;
(3)Builder模式的核心是“聚合”
三、單例模式【代碼參考例1中的Subject】
在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個實例。
“保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。”
單例模式的要點有三個;一是某個類只能有一個實例;二是它必須自行創建這個實例;三是它必須自行向整個系統提供這個實例。
具體實現角度來說,就是以下三點:一是單例模式的類只提供私有的構造函數,二是類定義中含有一個該類的靜態私有對象,三是該類提供了一個靜態的公有的函數用於創建或獲取它本身的靜態私有對象。
優點
一、實例控制
單例模式會阻止其他對象實例化其自己的單例對象的副本,從而確保所有對象都訪問唯一實例。
二、靈活性
因為類控制了實例化過程,所以類可以靈活更改實例化過程。
缺點
一、開銷
雖然數量很少,但如果每次對象請求引用時都要檢查是否存在類的實例,將仍然需要一些開銷。可以通過使用靜態初始化解決此問題。
二、可能的開發混淆
使用單例對象(尤其在類庫中定義的對象)時,開發人員必須記住自己不能使用new關鍵字實例化對象。因為可能無法訪問庫源代碼,因此應用程序開發人員可能會意外發現自己無法直接實例化此類。
三、對象生存期
不能解決刪除單個對象的問題。在提供內存管理的語言中(例如基於.NET Framework的語言),只有單例類能夠導致實例被取消分配,因為它包含對該實例的私有引用。在某些語言中(如 C++),其他類可以刪除對象實例,但這樣會導致單例類中出現懸浮引用。。
注意;在Android中的多線程中調用此方法應該在getInstance方法中用用synchronized來鎖定該類(這裡是Subject.class)
四、工廠模式【代碼參考例3】
工廠模式在《Java與模式》中分為三類:
//抽象產品角色 public interface Moveable { void run(); } //具體產品角色 public class Plane implements Moveable { @Override public void run() { System.out.println("plane...."); } } public class Broom implements Moveable { @Override public void run() { System.out.println("broom....."); } } //抽象工廠 public abstract class VehicleFactory { abstract Moveable create(); } //具體工廠 public class PlaneFactory extends VehicleFactory{ public Moveable create() { return new Plane(); } } public class BroomFactory extends VehicleFactory{ public Moveable create() { return new Broom(); } } //測試類 public class Test { public static void main(String[] args) { VehicleFactory factory = new BroomFactory(); Moveable m = factory.create(); m.run(); } }可以看出工廠方法的加入,使得對象的數量成倍增長。當產品種類非常多時,會出現大量的與之對應的工廠對象,這不是我們所希望的。因為如果不能避免這種情 況,可以考慮使用簡單工廠模式與工廠方法模式相結合的方式來減少工廠類:即對於產品樹上類似的種類(一般是樹的葉子中互為兄弟的)使用簡單工廠模式來實 現。
//抽象工廠類 public abstract class AbstractFactory { public abstract Vehicle createVehicle(); public abstract Weapon createWeapon(); public abstract Food createFood(); } //具體工廠類,其中Food,Vehicle,Weapon是抽象類, public class DefaultFactory extends AbstractFactory{ @Override public Food createFood() { return new Apple(); } @Override public Vehicle createVehicle() { return new Car(); } @Override public Weapon createWeapon() { return new AK47(); } } //測試類 public class Test { public static void main(String[] args) { AbstractFactory f = new DefaultFactory(); Vehicle v = f.createVehicle(); v.run(); Weapon w = f.createWeapon(); w.shoot(); Food a = f.createFood(); a.printName(); } }
例1:觀察者模式+單列模式
//觀察者接口【發現被觀察的對象的狀態或者數據發生改變時要做的事】 public interface CallBackObserver { void afterChangeDo();//被觀察的數據/狀態改變後執行 } class Observer_1 implements CallBackObserver{ private String observerName=""; public String getObserverName() { return observerName; } public void setObserverName(String observerName) { this.observerName = observerName; } //構造函數,傳入觀察者名稱,便於區分 public Observer_1(String observerName) { super(); this.observerName = observerName; } @Override public void afterChangeDo() { System.out.println(observerName+"執行afterChangeDo"); } } //被觀察者(類)的父類 public abstract class SubjectFather { public abstract void bindObserver(Observer_1 observer);//綁定 public abstract void disBindObserver(Observer_1 observer); //解綁 public abstract void notifyAllObserver(); //通知所有觀察者 } //被觀察者(實體類): class Subject extends SubjectFather{ private Listlist; /** * 這裡使用了單例模式(懶漢式)來構造一個Subject對象 * 單例模式:私有化構造函數,常用一個public static Subject getInstance()方法來獲得Subject的對象 */ private static Subject subject=null; public static Subject getInstance(){ if(subject == null){ subject = new Subject(); } return subject; } // 私有化構造函數【不允許在外部通過new來構造對象】 private Subject() { list = new ArrayList<>(); } @Override public void bindObserver(Observer_1 observer) { list.add(observer); System.out.println("綁定——"+observer.getObserverName()); } @Override public void disBindObserver(Observer_1 observer) { list.remove(observer); System.out.println("解綁——"+observer.getObserverName()); } public void dataChange(int i) { System.out.println("數據發生第"+i+"次改變"); notifyAllObserver(); } @Override public void notifyAllObserver() { for (Observer_1 observer_1 : list) { observer_1.afterChangeDo(); } } } //觀察者模式的演示類 public class ObserverDemo { public static void main(String[] args) { Subject subject = Subject.getInstance(); Observer_1 observer_1 = new Observer_1("觀察者1"); Observer_1 observer_2 = new Observer_1("觀察者2"); Observer_1 observer_3 = new Observer_1("觀察者3"); // 綁定 subject.bindObserver(observer_1); subject.bindObserver(observer_2); subject.bindObserver(observer_3); // 數據改變 subject.dataChange(1); subject.dataChange(2); subject.dataChange(3); // 解綁 subject.disBindObserver(observer_1); subject.disBindObserver(observer_2); subject.disBindObserver(observer_3); } }
運行結果:
綁定——觀察者1
綁定——觀察者2
綁定——觀察者3
數據發生第1次改變
觀察者1執行afterChangeDo
觀察者2執行afterChangeDo
觀察者3執行afterChangeDo
數據發生第2次改變
觀察者1執行afterChangeDo
觀察者2執行afterChangeDo
觀察者3執行afterChangeDo
數據發生第3次改變
觀察者1執行afterChangeDo
觀察者2執行afterChangeDo
觀察者3執行afterChangeDo
解綁——觀察者1
解綁——觀察者2
解綁——觀察者3
例2:Builder簡單寫法[寫法有很多種,可以自己多去嘗試]
public class Apple { private String name; //名稱 private double price; //價格 private int color; //顏色 private int memory; //存儲空間大小 private int mode; //聯網方式 //構造函數私有化,防止直接生成對象 private Apple(String name, double price, int color, int memory, int mode) { super(); this.name = name; this.price = price; this.color = color; this.memory = memory; this.mode = mode; } //測試用 @Override public String toString() { return "Apple [name=" + name + ", price=" + price + ", color=" + color + ", memory=" + memory + ", mode=" + mode + "]"; } static class Builder{ private String name; //名稱 private double price; //價格 private int color; //顏色 private int memory; //存儲空間大小 private int mode; public Apple build(){ //返回Apple的對象 //可以在這裡設置默認值【當傳入值為空或者沒有set時的默認值】 return new Apple(name,price,color,memory,mode); } //方法返回是Builder,就可以一直使用.方法名,來調用Builder中的方法 //可以在方法中約束傳入的值得“范圍” public Builder setName(String name) { this.name = name; return this; } public Builder setPrice(double price) { this.price = price; return this; } public Builder setColor(int color) { this.color = color; return this; } public Builder setMemory(int memory) { this.memory = memory; return this; } public Builder setMode(int mode) { this.mode = mode; return this; } } }
//測試Builder的Demo public class TespBuilder { public static void main(String[] args) { Apple apple = new Apple.Builder() .setColor(0) .setMemory(64) .setMode(1) .setName("iphone5s") // .setPrice(2600) .build(); System.out.println(apple); } }運行結果:
Apple [name=iphone5s, price=0.0, color=0, memory=64, mode=1]
一個超炫的引導界面,分享給大家代碼:MainActivity.javapackage com.bzu.gxs.webview1;import android.app.Ac
package c.example.jreduch09;import android.os.AsyncTask;import android.os.Bundle;impo
適配:即當前應用在相同的手機上面顯示相同的效果。適配前需要首先確定當前手機所屬像素密度類型(如:xhdpi、hdpi、mdpi等) 像素密度:每英寸上分布的像素點個數,單
使用AS從代碼托管中心下載項目(我使用的是Coding托管代碼)1、打開Android Studio,如果之前沒有打開過任何項目,那麼將會看到下面的啟動頁面,並選擇Che