定義
定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪個(gè)類棚唆。工廠方法模式是創(chuàng)建型設(shè)計(jì)模式
一個(gè)普通的例子
- 工廠和產(chǎn)品的關(guān)系
UML圖
工廠方法模式
源代碼
-
普通模式
- 普通的類與抽象類調(diào)用
-
常用模式
范型和反射構(gòu)造的,類似這樣
public <T extends AudiCar> T createAudiCar(Class<T> clz) {
AudiCar car = null;
try {
//用反射構(gòu)造具體的AudiCar對(duì)象
car = (AudiCar) Class.forName(clz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) car;
}
例子
一璃俗、普通模式
普通的抽象類和類調(diào)用的方式
- 抽象產(chǎn)品類
/** 抽象產(chǎn)品類
* Created by Niwa on 2017/7/22.
*/
public abstract class Product {
/**
* 產(chǎn)品類的抽象方法
* 由具體的產(chǎn)品類去實(shí)現(xiàn)
*
* */
public abstract void method();
}
- 具體產(chǎn)品類A
/** 具體產(chǎn)品類A
* Created by Niwa on 2017/7/22.
*/
public class ConcreteProductA extends Product{
public ConcreteProductA() {
}
@Override
public void method() {
System.out.println("我是具體的產(chǎn)品類A");
}
}
- 具體產(chǎn)品類B
/** 具體產(chǎn)品類B
* Created by Niwa on 2017/7/22.
*/
public class ConcreteProductB extends Product{
public ConcreteProductB() {
}
@Override
public void method() {
System.out.println("我是具體的產(chǎn)品類A");
}
}
- 抽象工廠類
/**
* 抽象工廠類
* Created by Niwa on 2017/7/22.
*/
public abstract class Factory {
/**
* 抽象工廠方法
* 具體生成什么由子類去實(shí)現(xiàn)
*
* @return 具體的產(chǎn)品類
*/
public abstract Product createProduct();
}
- 具體的工廠類章蚣,關(guān)鍵在這里頭,生成什么產(chǎn)品的方法
/** 具體的工廠類
* Created by Niwa on 2017/7/22.
*/
public class ConcreteFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
// return new ConcreteProductB();
}
}
- 測(cè)試
public static void main(String[] args){
Factory factory = new ConcreteFactory();
ConcreteProductA concreteProductA = (ConcreteProductA) factory.createProduct();
concreteProductA.method();
}
結(jié)果:
我是具體的產(chǎn)品類A
二迎瞧、反射構(gòu)造模式
奧迪Q5,Q7和工廠的故事
- 奧迪汽車抽象產(chǎn)品類
/** 奧迪汽車抽象產(chǎn)品類
* Created by Niwa on 2017/7/25.
*/
public abstract class AudiCar {
/**
* 車開走方法
*
* */
public abstract void drive();
/**
* 車自動(dòng)導(dǎo)航
*
* */
public abstract void selfNavigation();
}
- Q5和Q7
/**
* 奧迪汽車具體產(chǎn)品類Q5
* Created by Niwa on 2017/7/25.
*/
public class AudiQ5 extends AudiCar {
@Override
public void drive() {
System.out.println("Q5啟動(dòng)");
}
@Override
public void selfNavigation() {
System.out.println("Q5開始自動(dòng)導(dǎo)航");
}
}
/**
* 奧迪汽車具體產(chǎn)品類Q7
* Created by Niwa on 2017/7/25.
*/
public class AudiQ7 extends AudiCar {
@Override
public void drive() {
System.out.println("Q7啟動(dòng)");
}
@Override
public void selfNavigation() {
System.out.println("Q7開始自動(dòng)導(dǎo)航");
}
}
- 奧迪的抽象工廠類
/**
* 奧迪的抽象工廠類
* Created by Niwa on 2017/7/25.
*/
public abstract class AudiFactory {
/**
* 這里的范型<T>指定很關(guān)鍵
* 某車型的工廠方法逸吵,創(chuàng)建某車型對(duì)象
*
* @param clz 具體的suv 型號(hào)類型
* @return 具體型號(hào)的suv車對(duì)象
*/
public abstract <T extends AudiCar> T createAudiCar(Class<T> clz);
}
- 具體的奧迪汽車工廠凶硅,關(guān)鍵在這里,反射構(gòu)造具體的AudiCar對(duì)象
/**
* 具體的奧迪汽車工廠
* Created by Niwa on 2017/7/25.
*/
public class AudiCarFactory extends AudiFactory {
@Override
public <T extends AudiCar> T createAudiCar(Class<T> clz) {
AudiCar car = null;
try {
//用反射構(gòu)造具體的AudiCar對(duì)象
car = (AudiCar) Class.forName(clz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) car;
}
}
- 測(cè)試扫皱,
public static void main(String[] a){
//構(gòu)造一個(gè)制造汽車的工廠對(duì)象
AudiCarFactory audiCarFactory = new AudiCarFactory();
//生產(chǎn)Q5
AudiQ5 audiQ5 = audiCarFactory.createAudiCar(AudiQ5.class);
audiQ5.drive();
audiQ5.selfNavigation();
//生產(chǎn)Q7
AudiQ7 audiQ7 = audiCarFactory.createAudiCar(AudiQ7.class);
audiQ7.drive();
audiQ7.selfNavigation();
}
結(jié)果:
Q5啟動(dòng)
Q5開始自動(dòng)導(dǎo)航
Q7啟動(dòng)
Q7開始自動(dòng)導(dǎo)航
源代碼:DesignPattern
參考:
《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)讀書》
各大佬博客
end