## 工程方法模式
**定義**:定義一個用于創建對象的接口,讓子類決定實例化哪一個類,工廠方法使一個類的實例化延遲到其子類。
**我的理解**:工廠方法模式不是通過new關鍵字來創建對象的,而是通過工廠接口提供的方法來創建其他對象。
工廠設計模式,在開發過程中很常見,下面使用一個例子來引入普遍的工廠設計模式。
一個加工廠商加工不同的產品。
Product類,抽象類,表示不同的產品。
FoodProduct類,繼承Product類,并實現其抽象方法。
FruitProduct類,繼承Product類,并實現其抽象方法。
Creator類,是一個抽象工廠類,提供加工的方法。
NumberOneCreator類,表示一號工廠,實現其Creator類,用于加工不同的產品類。

~~~
public class FactoryTest {
public static void main(String[] args) {
//通過創建子類對象,將接口實例化。
Creator cFactory = new NumberOneCreator();
//通過子類的方法,創建一個需要的對象。
FoodProduct food = cFactory.createProduce(FoodProduct.class);
food.mothod1();
food.mothod2();
}
}
//定義一個抽象的產品方法。
abstract class Product{
public void mothod1(){
System.out.println("方法一,加工的都是使用的產品...");
}
public abstract void mothod2();
}
class FruitProduct extends Product{
@Override
public void mothod2() {
System.out.println("方法二,生產出來了果汁....");
}
}
class FoodProduct extends Product{
@Override
public void mothod2() {
System.out.println("方法二,生產出來了零食....");
}
}
abstract class Creator{
public abstract <T extends Product> T createProduce(Class<T> t);
}
class NumberOneCreator extends Creator{
/**
* 傳入的參數,是Product類的子類。
*/
@Override
public <T extends Product> T createProduce(Class<T> t) {
Product p = null;
try {
//Class類創建一個 工廠類實例
p = (Product) Class.forName(t.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) p;
}
}
~~~
工廠模式的優點:
1、具有良好的封裝性,代碼結構清晰。降低模塊間的耦合性
2、工廠方法模式的擴展性非常優秀。
3、屏蔽產品類,產品類對外提供的是一個接口,只要接口不改變系統中的上層模塊就不會發生改變。
## 工廠模式的擴展:
**1、縮小為簡單的工廠模式(靜態工廠模式)**
?? 一個模塊僅需要一個工廠類,沒有必要把它產生出來,使用靜態的方法就可以了。
?? ---該模式稱為簡單工廠模式(又稱靜態工廠模式)。調用者使用十分方便,開發中也經常用到,但是擴展不好。
?? UML類圖

~~~
public class NvWatest {
public static void main(String[] args) {
YellowMan yellowMan = HumanFactory.CreatHuman(YellowMan.class);
yellowMan.skin();
yellowMan.talk();
}
}
interface Human{
//人類的語言
void talk();
//人類的膚色
void skin();
}
class BlackMan implements Human{
@Override
public void talk() {
System.out.println("我是黑種人,我說的是非洲語...");
}
@Override
public void skin() {
System.out.println("我是黑種人,我的皮膚是黑色的...");
}
}
class WhiteMan implements Human{
@Override
public void talk() {
System.out.println("我是白種人,我說的是英語...");
}
@Override
public void skin() {
System.out.println("我是白種人,我的皮膚是白色的...");
}
}
class YellowMan implements Human{
@Override
public void talk() {
System.out.println("我是黃種人,我說的是漢語...");
}
@Override
public void skin() {
System.out.println("我是黃種人,我的皮膚是黃色的...");
}
}
class HumanFactory{
public static <T extends Human> T CreatHuman(Class<T> c){
Human man = null;
try {
man = (Human) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) man;
}
}
~~~
**2、升級為多個設計模式**
將工廠類劃分為YellowFactory,BlackFactory,WhiteFactory三類,都繼承自抽象工廠。
這三中工廠分成實現創造不同的人類。
UML圖

~~~
public class NvWatest {
public static void main(String[] args) {
YellowMan yellowMan = (YellowMan) new YellowHumanFactory().CreatHuman();
yellowMan.skin();
yellowMan.talk();
}
}
interface Human{
//人類的語言
void talk();
//人類的膚色
void skin();
}
class BlackMan implements Human{
@Override
public void talk() {
System.out.println("我是黑種人,我說的是非洲語...");
}
@Override
public void skin() {
System.out.println("我是黑種人,我的皮膚是黑色的...");
}
}
class WhiteMan implements Human{
@Override
public void talk() {
System.out.println("我是白種人,我說的是英語...");
}
@Override
public void skin() {
System.out.println("我是白種人,我的皮膚是白色的...");
}
}
class YellowMan implements Human{
@Override
public void talk() {
System.out.println("我是黃種人,我說的是漢語...");
}
@Override
public void skin() {
System.out.println("我是黃種人,我的皮膚是黃色的...");
}
}
abstract class AbstractHumanFactory{
public abstract Human CreatHuman();
}
class BlackHumanFactory extends AbstractHumanFactory{
@Override
public Human CreatHuman() {
// TODO Auto-generated method stub
return new BlackMan();
}
}
class YellowHumanFactory extends AbstractHumanFactory{
@Override
public Human CreatHuman() {
// TODO Auto-generated method stub
return new YellowMan();
}
}
class WhiteHumanFactory extends AbstractHumanFactory{
@Override
public Human CreatHuman() {
// TODO Auto-generated method stub
return new WhiteMan();
}
}
~~~
以下兩種暫時不懂得利用的價值,但是還是先了解一下為好
**3、替代單例模式**
創建一個單例工廠,來創建需要創建的類。并保證只有一個實例對象。

~~~
public class SingletonTest {
public static void main(String[] args) {
Singleton s = new SingtonFactory().getSingle();
s.mothod1();
}
}
class SingtonFactory{
private static Singleton single;
static{
try {
Class c = Class.forName(Singleton.class.getName());
//獲得無參構造
Constructor<Singleton> constractor = c.getDeclaredConstructor();
//設置無參構造是可訪問的
constractor.setAccessible(true);
//產生一個實例對象
single = constractor.newInstance();
} catch (Exception e) {
System.out.println("創建實例失敗...");
}
}
public Singleton getSingle(){
return single;
}
}
class Singleton{
//不讓外界調用者創建實例
private Singleton(){
}
public void mothod1(){
System.out.println("sington的一個方法....");
}
}
~~~
**4、延遲初始化**
一個對象被消費完畢后,并不立刻釋放,工廠類保持其初始狀態,等待再次被使用。

~~~
public class FactoryTest {
public static void main(String[] args) {
for(int i=0;i<5;i++){
Product p = new Creator().createProduce("food");
p.mothod1();
p.mothod2();
System.out.println("------------------------------");
}
}
}
//定義一個抽象的產品方法。
abstract class Product{
public void mothod1(){
System.out.println("方法一,加工的都是使用的產品...");
}
public abstract void mothod2();
}
class FruitProduct extends Product{
@Override
public void mothod2() {
System.out.println("方法二,生產出來了果汁....");
}
}
class FoodProduct extends Product{
@Override
public void mothod2() {
System.out.println("方法二,生產出來了零食....");
}
}
class Creator {
private static Map<String,Product> map = new HashMap<String, Product>();
public static synchronized Product createProduce(String type) {
Product p = null;
//首先判斷map集合中是否存在該對象
if(map.containsKey(type)){
System.out.println("-----------存在該對象-------------");
p = map.get(type);
}else{
//如果不存在,就根據類型來創建不同的實例
if(type.equals("food")){
p = new FoodProduct();
}else{
p = new FruitProduct();
}
}
map.put(type, p);
return p;
}
}
~~~
- 前言
- 6大設計原則(一)---單一職責原則
- 6大設計原則(二)---里氏替換原則
- 6大設計原則(三)---依賴倒置原則
- 6大設計模式(四)----接口隔離原則
- 6大設計原則(五)---迪米特法則
- 6大設計原則(六)---開閉原則。
- 設計模式(一)---單例模式
- 設計模式(二)---工廠方法模式
- 設計模式(三)---抽象工廠模式
- 設計模式(四)---模板方法模式
- 設計模式(五)---建造者模式
- 設計模式(六)---代理模式
- 設計模式(七)---原型模式
- 設計模式(八)---中介者模式
- 設計模式(九)---命令模式
- 設計模式(十)---責任鏈模式
- 設計模式(十一)---裝飾模式
- 設計模式(十二)---策略模式
- 設計模式(十三)---適配器模式
- 設計模式(十四)---迭代器模式
- 設計模式(十五)---組合模式
- 設計模式(十六)---觀察者模式
- 設計模式(十七)---門面模式
- 設計模式(十八)---備忘錄模式
- 設計模式(十八)---訪問者模式
- 設計模式(二十)---狀態模式
- 設計模式(二十二)---享元模式
- 設計模式(二十三)---橋梁模式