前言
工廠模式中恨溜,重要的是工廠類符衔,而不是產(chǎn)品類。產(chǎn)品類可以是多種形式糟袁,多層繼承或者是單個類都是可以的判族。但要明確的,工廠模式的接口只會返回一種類型的實例系吭,這是在設(shè)計產(chǎn)品類的時候需要注意的五嫂,最好是有父類或者共同實現(xiàn)的接口。
使用工廠模式肯尺,返回的實例一定是工廠創(chuàng)建的沃缘,而不是從其他對象中獲取的。
工廠模式返回的實例可以不是新創(chuàng)建的则吟,返回由工廠創(chuàng)建好的實例也是可以的槐臀。
工廠模式主要是為創(chuàng)建對象提供了接口。工廠模式按照《Java與模式》中的提法分為三類:
- 簡單工廠模式(Simple Factory)
- 工廠方法模式(Factory Method)
- 抽象工廠模式(Abstract Factory)
1氓仲、工廠模式 - 簡單工廠模式
簡單工廠優(yōu)點:客戶端可以免除直接創(chuàng)建產(chǎn)品對象的責(zé)任水慨,而僅僅是“消費”產(chǎn)品。簡單工廠模式通過這種做法實現(xiàn)了對責(zé)任的分割敬扛。
1.1晰洒、 簡單工廠模式UML圖
1.2、 代碼實現(xiàn)
定義接口
/**
* 地圖規(guī)范
* @author Dream
*
*/
public interface IMapView {
enum MapType {
// 空白背景模式常量
MAP_TYPE_NONE,
// 普通地圖模式常量
MAP_TYPE_NORMAL,
// 衛(wèi)星圖模式常量
MAP_TYPE_SATELLITE
}
public View getView();
public void setMapType(MapType mapType);
}
實現(xiàn)接口
public class BaiduMapView implements IMapView {
@Override
public View getView() {
System.out.println("調(diào)用了百度地圖的getView");
return null;
}
@Override
public void setMapType(MapType mapType) {
System.out.println("調(diào)用了百度地圖的setMapType");
}
}
public class GaodeMapView implements IMapView {
@Override
public View getView() {
System.out.println("調(diào)用了高德地圖的getView");
return null;
}
@Override
public void setMapType(MapType mapType) {
System.out.println("調(diào)用了高德地圖的setMapType");
}
}
創(chuàng)建工廠類
public class MapViewFactory {
enum MapType{
Baidu,
Gaode
}
//使用上一節(jié)課的內(nèi)容---單例模式
//懶漢式
private static MapViewFactory mapViewFactory;
private MapViewFactory(){
}
public static MapViewFactory getInstance(){
if(mapViewFactory == null){
mapViewFactory = new MapViewFactory();
ArrayList<String> list = new ArrayList<String>();
HashSet<String> hashSet = new HashSet<String>();
}
return mapViewFactory;
}
public IMapView getMapView(MapType mapType){
IMapView mapView = null;
switch (mapType) {
case Baidu:
mapView = new BaiduMapView();
break;
case Gaode:
mapView = new GaodeMapView();
break;
}
return mapView;
}
}
調(diào)用主函數(shù)
public class SimpleTest {
public static void main(String[] args) {
// 客戶端和我們的地圖模塊耦合度大大降低了
IMapView mapView = MapViewFactory.getInstance().getMapView(
MapViewFactory.MapType.Baidu);
mapView.getView();
mapView.setMapType(IMapView.MapType.MAP_TYPE_NONE);
}
}
運行結(jié)果
獲得百度地圖MapView
設(shè)置了高德地圖類型
獲得高德地圖MapView
設(shè)置了高德地圖類型
1.3啥箭、Android源碼中使用
Android中簡單工廠--BitmapFactory,XmlPullParserFactory,CertificateFactory
2谍珊、工廠模式 - 工廠方法模式
工廠方法模式:把對象的實現(xiàn)延遲到子類完成
工廠方法優(yōu)點:允許系統(tǒng)在不修改具體工廠角色的情況下引進新產(chǎn)品。
2.1急侥、 工廠方法模式UML圖
2.2砌滞、 代碼實現(xiàn)
產(chǎn)品接口與實現(xiàn)(Mapview)
//接口
public abstract class IMapView {
public abstract void onStart();
public abstract void onResume();
public abstract void onDestory();
}
public class BaiduMapView extends IMapView {
@Override
public void onStart() {
System.out.println("百度地圖onStart");
}
@Override
public void onResume() {
System.out.println("百度地圖onResume");
}
@Override
public void onDestory() {
System.out.println("百度地圖onDestory");
}
}
public class GaodeMapView extends IMapView {
@Override
public void onStart() {
System.out.println("高德地圖onStart");
}
@Override
public void onResume() {
System.out.println("高德地圖onResume");
}
@Override
public void onDestory() {
System.out.println("高德地圖onResume");
}
}
抽象工廠
//抽象
public abstract class AbsMapFactory {
// 我只定義標準
public abstract <T extends IMapView> T createMapView(Class<T> clzz);
}
實現(xiàn)工廠
public class DefaultMapFactory extends AbsMapFactory {
private static DefaultMapFactory defaultMapFactory;
private DefaultMapFactory() {
}
public static DefaultMapFactory getInstance(){
if(defaultMapFactory == null){
defaultMapFactory = new DefaultMapFactory();
}
return defaultMapFactory;
}
@Override
public <T extends IMapView> T createMapView(Class<T> clzz) {
try {
// 反射
return clzz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
調(diào)用主函數(shù)
public class TestClient {
public static void main(String[] args) {
//工廠方法模式
AbsMapFactory factory = DefaultMapFactory.getInstance();
BaiduMapView mapView = factory.createMapView(BaiduMapView.class);
mapView.onStart();
}
}
運行結(jié)果
百度地圖onStart
2.2、 Java或Android中源碼運用
分析List集合坏怪、Set集合贝润、Map集合 源碼
lterator:遍歷集合工廠方法抽象
Itr:具體的工廠實現(xiàn)類
lterator-> 抽象(工廠方法抽象) -->AdsMapFactory
Itr ->具體實現(xiàn)類->DefaultMapFactory
AbstractList-> 抽象 -->ImapView
ArrayList-> 實現(xiàn)類--> BaiduMapView
3、工廠模式 - 抽象工廠模式
為了增加導(dǎo)航模塊铝宵、全景圖口快打掘、定位模塊而不僅僅是地圖模塊引入抽象工廠模式 (一組類要求相同約束)
抽象工廠優(yōu)點:向客戶端提供一個接口,使得客戶端在不必指定產(chǎn)品具體類型的情況下,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象
3.1胧卤、 抽象工廠模式UML圖
3.2唯绍、 代碼實現(xiàn)
抽象工廠
public abstract class AbsMapFactory {
public abstract AbsMapView createMapView();
public abstract AbsMapNavigation createMapNavigation();
public abstract AbsMapLocation createMapLocation();
}
各種具體工廠
public class GaodeMapFactory extends AbsMapFactory {
@Override
public AbsMapView createMapView() {
return new GaodeMapView();
}
@Override
public AbsMapNavigation createMapNavigation() {
return new GaodeMapNavigation();
}
@Override
public AbsMapLocation createMapLocation() {
return new GaodeMapLocation();
}
}
public class BaiduMapFactory extends AbsMapFactory {
@Override
public AbsMapView createMapView() {
return new BaiduMapView();
}
@Override
public AbsMapNavigation createMapNavigation() {
return new BaiduMapNavigation();
}
@Override
public AbsMapLocation createMapLocation() {
return new BaiduMapLocation();
}
}
初始化工廠
public class DefaultFactory {
//使用反射
public static <T extends AbsMapFactory> T creatProduct(Class<T> clz){
AbsMapFactory api =null;
try {
api =(AbsMapFactory) Class.forName(clz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T)api;
}
}
工廠內(nèi)各產(chǎn)品
定位產(chǎn)品
public abstract class AbsMapLocation {
/**
* 定位
*/
public abstract void location();
}
public class BaiduMapLocation extends AbsMapLocation {
@Override
public void location() {
System.out.println("百度地圖定位...");
}
}
public class GaodeMapLocation extends AbsMapLocation {
@Override
public void location() {
System.out.println("高德地圖定位...");
}
}
地圖產(chǎn)品
public abstract class AbsMapView {
/**
* Result for IActivityManager.startActivity: an error where the
* start had to be canceled.
* @hide
*/
public abstract void onStart();
public abstract void onResume();
public abstract void onDestory();
}
public class BaiduMapView extends AbsMapView {
@Override
public void onStart() {
System.out.println("百度地圖調(diào)用了onStart");
}
@Override
public void onResume() {
System.out.println("百度地圖調(diào)用了onResume");
}
@Override
public void onDestory() {
System.out.println("百度地圖調(diào)用了onDestory");
}
}
public class GaodeMapView extends AbsMapView {
@Override
public void onStart() {
System.out.println("高德地圖調(diào)用了onStart");
}
@Override
public void onResume() {
System.out.println("高德地圖調(diào)用了onResume");
}
@Override
public void onDestory() {
System.out.println("高德地圖調(diào)用了onDestory");
}
}
導(dǎo)航產(chǎn)品
public abstract class AbsMapNavigation {
/**
* 路線規(guī)劃
*/
public abstract void turnByTurn();
//......很多功能方法
}
public class BaiduMapNavigation extends AbsMapNavigation {
@Override
public void turnByTurn() {
System.out.println("百度地圖導(dǎo)航路線規(guī)劃");
}
}
public class GaodeMapNavigation extends AbsMapNavigation {
@Override
public void turnByTurn() {
System.out.println("高德地圖導(dǎo)航功能路線規(guī)劃");
}
}
調(diào)用主函數(shù)
public class Test {
public static void main(String[] args) {
//直接初始化某地圖
AbsMapFactory factory = new BaiduMapFactory();
factory.createMapView().onStart();
factory.createMapLocation().location();
//反射初始化某地圖
AbsMapFactory factory2 = DefaultFactory.creatProduct(GaodeMapFactory.class);
factory2.createMapView().onStart();
factory2.createMapLocation().location();
}
}
運行結(jié)果
百度地圖調(diào)用了onStart
百度地圖定位...
高德地圖調(diào)用了onStart
高德地圖定位...
3.3、 Android源碼中使用
Activity、Service --- AbsMapView或者AbsMapNavgation
我們自定義的Activity(如BaseActivity)、Service ---BaiduMapView 或 BaiduMapNavgation
ActivityManager么伯、ServiceManager --- 類似于我們通常所說的AbsMapFactory
總結(jié):
簡單工廠 : 用來生產(chǎn)同一等級結(jié)構(gòu)中的任意產(chǎn)品忍饰。(對于增加新的產(chǎn)品,無能為力)
工廠方法 :用來生產(chǎn)同一等級結(jié)構(gòu)中的固定產(chǎn)品耐版。(支持增加任意產(chǎn)品)
抽象工廠 :用來生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品祠够。(對于增加新的產(chǎn)品,無能為力粪牲;支持增加產(chǎn)品族)
以上三種工廠 方法在等級結(jié)構(gòu)和產(chǎn)品族這兩個方向上的支持程度不同古瓤。所以要根據(jù)情況考慮應(yīng)該使用哪種方法。