編輯:關於Android編程
工廠模式是一種創建者模式,在任何生成復雜對象的地方都可以使用工廠模式。理論來說在任何使用A a = new A()的方式都可以使用工廠模式,雖然使用工廠模式可能需要多做一些工作,但是在後續的開發和維護都帶來了方便。
如果我們需要在構建對象的時候,需要做很多的處理工作,比如初始化工作,查詢工作等一些耗時的工作,如果我們將這些操作全部放入到構造方法中去寫,那麼勢必在後期維護的帶來不方便,而且始化工作如果是很長一段代碼,說明要做的工作很多,將很多工作裝入一個方法中,相當於將很多雞蛋放在一個籃子裡,是很危險的,這也是有悖於Java面向對象的原則,面向對象的封裝(Encapsulation)和分派(Delegation)告訴我們,盡量將長的代碼分派“切割”成每段,將每段再“封裝”起來(減少段和段之間耦合聯系性),這樣,就會將風險分散,以後如果需要修改,只要更改每段,不會再發生牽一動百的事情。
工廠模式分類
簡單工廠模式 工廠模式
抽象工廠模式
三者之間的區別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。 工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。 簡單工廠模式只有一個抽象產品類,一個工廠類
簡單工廠模式
簡單工廠模式,一個具體工廠類負責生產所有的具體產品。客戶端只需要關注生成的具體產品。
簡單工廠模式的uml圖
- Factory : 負責生產具體的產品工廠
- Product: 抽象的產品類,
- P1: 具體的產品類P1
- P2: 具體的產品類P2
舉個例子。
汽車工廠造汽車的例子。首先Rrtoyewx在大眾廠裡面上班,一開始被分配到了上海大眾裡面去了,只管Passat和polo兩款車型,而且做的事很簡單,就是簡單開出去測試一下車子的性能。這個時候事務較少,Rrtoyewx覺得用簡單工廠就能搞定了。
package圖如下:
- Volkswagen:抽象的大眾汽車類
- Passat,Polo:具體的大眾汽車類
- ShangHaiVolkswagenFactory: 上海大眾汽車工廠
- Client: 客戶端類
產品類
Volkswagen
public interface Volkswagen {
void drive();
String getName();
}
Passat
public class Passat implements Volkswagen {
public static final int ID = 0;
@Override
public void drive() {
System.out.println("Passat開出去咯,測試成功");
}
@Override
public String getName() {
return "Passat";
}
}
Polo
public class Polo implements Volkswagen{
public static final int ID = 1;
@Override
public void drive() {
System.out.println("Polo開出去咯,測試成功");
}
@Override
public String getName() {
return "Polo";
}
}
工廠類
public class ShangHaiVolkswagenFactory {
public Volkswagen createVolkswagen(int id){
Volkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
}
客戶端類
public class Client {
public static void main(String[] args) {
ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
Volkswagen passat = factory.createVolkswagen(Passat.ID);
passat.drive();
Volkswagen polo = factory.createVolkswagen(Polo.ID);
System.out.println(polo.getName());
}
}
打印出的log為
每次測試的時候Client類都跑了一遍,似乎很簡單,同樣的也方便以後的擴展(添加新的車型的時候),只需要添加一個產品類,然後在工廠裡添加響應的邏輯就行了。Rrtoyewx覺得自己這個測試車輛程序完全夠用了。
注意對於上面的工廠,可以采用反射的形式去創建產品類,如下面的代碼<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
public class ShangHaiVolkswagenFactory {
//產品的id
public Volkswagen createVolkswagen(int id){
Volkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
//反射得到
public Volkswagen createVolkswagen(Class clazz){
Volkswagen volkswagen = null;
try {
volkswagen = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return volkswagen;
}
}
優點:客戶端需要的什麼產品,可以直接得到,邏輯判斷在工廠裡面,
缺點:擴展性一般,產品都是一個產品族下面的產品,對於不在產品族中的產品,沒辦法去擴展,另外獲得具體某種產品的邏輯放在工廠裡面,新添加產品的時候就需要修改工廠裡面的代碼。
- AbstractProduct:抽象的產品類
- ProductA:具體的A產品
- ProductB:具體的B產品
- AbstractFactory:抽象工廠類
- FactoryA:具體的生產A產品的工廠類
- FactoryB:具體的生產B產品的工廠類
- Client: 客戶端類
還是上面的栗子的。Rrtoyewx在負責上海大眾的兩款車型,本來就著簡單工廠的模式測試車輛的時候,日子過的非常好,可是好景不長,突然有一天領導說Rrtoyewx說:一汽大眾廠最近較忙,看你比較清閒,你就順便把一汽大眾的邁騰,和速騰都測一下。本來Rrtoyewx覺得挺簡單的,就是簡單再添加一個Magotan和Sagitar,然後通過工廠生成就行了,可是等Rrtoyewx一拿到測試的項目的時候,發現並不是只測試drive,Sagitar和Magotan不僅需要測試drive,而且需要測試brake。好吧,Rrtoyewx覺得以前寫的都不能夠用了。想了很久,Rrtoyewx 覺得需要將簡單工廠模式升級到工廠模式,關注點也發生了改變不再為具體的車輛的,而是一汽大眾的車(Magotan和Sagitar)還是上海大眾的車(Passat和 Polo)了
修改過後的package圖:
- Volkswagen: 抽象的汽車類
- ShangHaiVolkswagen:上海大眾汽車的抽象類
- FAWVolkswagen:一汽大眾汽車的抽象類
- Passat,Polo:上海大眾廠汽車類的具體類
- Magotan,Sagitar:一汽大眾廠汽車的具體類
- VolkswagenFactory:抽象的大眾汽車工廠
- ShangHaiVolkswagenFactory:上海大眾汽車工廠,主要負責測試Passat和Polo
- FAWVolkswagenFactory:一汽大眾的工廠,主要負責測試Magotan和Sagitar
Volkswagen類,將Volkswagen類轉成抽象類
public abstract class Volkswagen {
public abstract void drive();
public abstract String getName();
}
ShangHaiVolkswagen:上海大眾汽車的抽象類
public abstract class ShangHaiVolkswagen implements Volkswagen{
}
FAWVolkswagen : 一汽大眾汽車的抽象類,多了一個brake()的方法
public abstract class FAWVolkswagen implements Volkswagen {
public abstract void brake();
}
VolkswagenFactory : 汽車工廠的抽象類,並將createVolkswagen(Class clazz)聲明稱final類型。供子類使用
public abstract class VolkswagenFactory {
public abstract Volkswagen createVolkswagen(int productID);
public final Volkswagen createVolkswagen(Class clazz){
Volkswagen volkswagen = null;
try {
volkswagen = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return volkswagen;
};
}
上海大眾的具體實現類
Passat類
public class Passat extends ShangHaiVolkswagen {
public static final int ID = 0;
@Override
public void drive() {
System.out.println("Passat開出去咯,測試成功");
}
@Override
public String getName() {
return "Passat";
}
}
Polo類
public class Polo extends ShangHaiVolkswagen{
public static final int ID = 1;
@Override
public void drive() {
System.out.println("Polo開出去咯,測試成功");
}
@Override
public String getName() {
return "Polo";
}
}
一汽大眾的汽車類。
Sagitar類,
public class Sagitar extends FAWVolkswagen {
public static final int ID = 2;
@Override
public void drive() {
System.out.println("Sagitar 開出去了,測試成功了");
}
@Override
public String getName() {
return "Sagitar";
}
@Override
public void brake(){
System.out.println("Sagitar 剎車挺好的,測試通過了");
}
}
Magotan 類
public class Magotan extends FAWVolkswagen{
public static final int ID = 3;
@Override
public void drive() {
System.out.println("Magotan 開出去咯,測試成功了");
}
@Override
public String getName() {
return "Magotan";
}
@Override
public void brake(){
System.out.println("Magotan 剎車挺好的,測試通過");
}
}
注意重載方法的返回類型已經修改稱對應的產品類,不在是Volkswagen類型了
ShangHaiVolkswagenFactory:負責生產上海汽車的工廠類
public class ShangHaiVolkswagenFactory extends VolkswagenFactory {
public ShangHaiVolkswagen createVolkswagen(int id){
ShangHaiVolkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
}
FAWVolkswagenFactory:負責生產一汽汽車的工廠類
public class FAWVolkswagenFactory extends VolkswagenFactory {
@Override
public FAWVolkswagen createVolkswagen(int productID) {
FAWVolkswagen volkswagen = null;
switch(productID){
case Magotan.ID:
volkswagen = new Magotan();
break;
case Sagitar.ID:
volkswagen = new Sagitar();
break;
default:
volkswagen = null;
}
return volkswagen;
}
}
Client類:用來測試
public class Client {
public static void main(String[] args) {
System.out.println("開始測試上海大眾的車輛");
ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
ShangHaiVolkswagen passat = factory.createVolkswagen(Passat.ID);
passat.drive();
ShangHaiVolkswagen polo = factory.createVolkswagen(Polo.ID);
polo.drive();
System.out.println("開始測試一汽大眾的車輛");
FAWVolkswagenFactory fawFactory = new FAWVolkswagenFactory();
FAWVolkswagen magotan = fawFactory.createVolkswagen(Magotan.ID);
magotan.drive();
magotan.brake();
FAWVolkswagen sagitar = fawFactory.createVolkswagen(Sagitar.ID);
sagitar.drive();
sagitar.brake();
}
}
打印log的也能夠正確的測試:
通過下面的改變,Rrtoyewx將工廠抽象出生產上海大眾的車子和一汽大眾的車子的兩個工廠,並將一汽大眾和上海大眾的車子做了區分,形成兩個不同產品族的產品系列。並由兩個工廠分別對應去生產。等Rrtoyewx做完了這麼多後,終於發現原先的系統還是有漏洞的,還是有局限性的,好在及時的彌補。Rrtoyewx發現現有的系統無論處理一汽大眾的車子還是上海大眾的車子,甚至於再加一個進口大眾工廠的車子也夠用了。再以後的擴展也能得到了提升了。
優點:擴展性,能夠處理不同產品系列的產品,通過具體的工廠去生成不同產品族的產品,擴展性較好。
缺點:類的個數較多。另外一個工廠的只能夠生產一個具體的產品。
- AbstractFactory:抽象工廠類
- ConcreteFactoryA:具體工廠A,負責生產A和B的
- ConcreteFactoryB:具體工廠b,負責生產A和B的
- AbstractProductA,AbstractProductB:抽象的產品類
- ConcreteProductA1,ConcreteProductA2:具體產品A
- ConcreteProductB1,ConcreteProductB1:具體產品B
- Client:客戶端
Rrtoyewx在做完上面測試工作之後,上面領導覺得Rrtoyewx工作很不錯,想將Rrtoyewx逐漸管理業務層的事(與人打交道),將Rrtoyewx升級了部門經理,同樣責任也多了起來了,Rrtoyewx不僅測試原先一些東西,而且需要做一個額外的事情,比如說保險之類。Rrtoyewx在查閱的保險的相關的書籍發現,一汽大眾的工廠需要一等保險,而上海大眾的車子需要二等保險。 Rrtoyewx 這個時候發現的保險和車子不屬於同一個產品。為了處理事務方便Rrotowx需要將原先的系統給升級一下。
升級後的系統的package圖
新加了幾個類
Insurance:保險的抽象類
OneLevelInsurance:一等保險的實現類
TwoLevelInsurance:二等保險的實現類
Insurance類
public abstract class Insurance {
public abstract String getName();
}
OneLevelInsurance類
public class OneLevellnsurance extends Insurance{
@Override
public String getName() {
return "一級保險";
}
}
TwoLevelInsurance類
public class TwoLevelInsurance extends Insurance {
@Override
public String getName() {
return "二級保險";
}
}
同時修改ShangHaiVolkswagenFactory和FAWVolkswagenFactory以及VolkswagenFactory的代碼
具體如下
VolkswagenFactory 添加一個生成Insurance類的方法
public abstract class VolkswagenFactory {
public abstract Volkswagen createVolkswagen(int productID);
public abstract Insurance bindInsurance();
public final Volkswagen createVolkswagen(Class clazz){
Volkswagen volkswagen = null;
try {
volkswagen = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return volkswagen;
};
}
ShangHaiVolkswagenFactory綁定一等保險的對象
public class ShangHaiVolkswagenFactory extends VolkswagenFactory {
public ShangHaiVolkswagen createVolkswagen(int id){
ShangHaiVolkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
@Override
public Insurance bindInsurance() {
return new OneLevellnsurance();
}
}
FAWVolkswagenFactory類:並定二等保險的對象
public class FAWVolkswagenFactory extends VolkswagenFactory {
@Override
public FAWVolkswagen createVolkswagen(int productID) {
FAWVolkswagen volkswagen = null;
switch(productID){
case Magotan.ID:
volkswagen = new Magotan();
break;
case Sagitar.ID:
volkswagen = new Sagitar();
break;
default:
volkswagen = null;
}
return volkswagen;
}
@Override
public Insurance bindInsurance() {
return new TwoLevelInsurance();
}
}
Client客戶端測試的類
public class Client {
public static void main(String[] args) {
System.out.println("開始測試上海大眾的車輛");
ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
ShangHaiVolkswagen passat = factory.createVolkswagen(Passat.ID);
passat.drive();
ShangHaiVolkswagen polo = factory.createVolkswagen(Polo.ID);
polo.drive();
Insurance shanghaiInsurance = factory.bindInsurance();
System.out.println(shanghaiInsurance.getName());
System.out.println("開始測試一汽大眾的車輛");
FAWVolkswagenFactory fawFactory = new FAWVolkswagenFactory();
FAWVolkswagen magotan = fawFactory.createVolkswagen(Magotan.ID);
magotan.drive();
magotan.brake();
FAWVolkswagen sagitar = fawFactory.createVolkswagen(Sagitar.ID);
sagitar.drive();
sagitar.brake();
Insurance fawInsurance = fawFactory.bindInsurance();
System.out.println(fawInsurance.getName());
}
}
打印log為:
Rrtoyewx 做完這些,發現系統已經很健全了,不在為了測試車輛,只要與車輛相關的事宜的對象,由不同的工廠具體去實現。完成這麼多,Rrtoyewx 覺得天特別的藍,心情特別的舒服。
離線緩存就是在網絡暢通的情況下將從服務器收到的數據保存到本地,當網絡斷開之後直接讀取本地文件中的數據。如Json 數據緩存到本地,在斷網的狀態下啟動APP時讀
本文采用一個Demo來展示Android中ExpandableListView控件的使用,如如何在組/子ListView中綁定數據源。直接上代碼如下:程序結構圖:layo
首先我們看一下什麼叫做透明的進度對話框:接下來我們講一下如何創建:1、使用Eclipse創建一個新的Android 項目,使用Android
為了提高用戶體驗,我們肯定希望該Dialog能更加炫酷,讓用戶看著更舒服。那如何做呢,當然是我們自己定義一個ProgressDialog了。一、使用系統加載框mDialo