工廠方法模式
定義:Define an interface for creating an object, but let subclasses decide which class to instantiate.Factory method lets a class defer instantiation to subclasses.
定義一個用於創建對象的接口,讓子類決定實例化哪一個類,工廠方法使一個類的實例化延遲到其子類。
工場方法模式最適合於在創建對象、擴展的時候使用了
下面的這個框架是工場方法比較通用的,便於擴展。(當然,在定義接口來代替抽象產品類)
抽象產品類
public abstract class Product
{
//產品類公共方法
public void method1()
{
}
//抽象方法
public abstract void method2();
}
具體產品類
可以有多個具體產品類,都是繼承自抽象產品類
public class Productone extends Product
{
//必須實現抽象方法
public void method2()
{
}
}
public class Producttwo extends Product
{
//必須實現抽象方法
public void method2()
{
}
}
抽象工廠類
定義產品時使用
public abstract void Maker
{
/*
* 創建一個產品對象後,輸入參數類型可以自行設置
* 這裡使用到泛型,makeProduct裡的參數必須是Class類型且是Product的實現類
*/
public abstract <T extends Product> T makeProduct(Class<T> c);
}
具體工廠類
具體工廠類才是如何生產一個產品的類,實現抽象工廠類
public class ReadMaker extends Maker
{
public <T extends Product> T makeProduct(Class<T> c)
{
Product product = null;
try
{
product = (Product)Class.forName(c.getName()).newInstance();
}catch(Exception e)
{
//deal with exception
}
return (T)product;
}
}
場景類
public class Client
{
public static void main(String args[])
{
Maker maker = new ReadMaker();
Product product = maker.makeProduct(Product1.class);
}
}
下面是一個具體的例子,很直觀
定義一個抽象產品手機類
package com.loulijun.chapter8;
//手機類,包括很多
public abstract class Phone {
//打電話
public void call(){};
//音樂
public void music(){};
//上網
public void via_internet(){};
}
實現產品類1:實現一個iphone
package com.loulijun.chapter8;
public class iPhone extends Phone {
@Override
public void call() {
System.out.println("用iphone打電話");
}
@Override
public void music() {
System.out.println("用iphone聽音樂");
}
@Override
public void via_internet() {
System.out.println("用iphone上網");
}
}
實現產品類2:Android手機
package com.loulijun.chapter8;
public class AndroidPhone extends Phone {
@Override
public void call() {
System.out.println("用Android手機打電話");
}
@Override
public void music() {
System.out.println("用Android手機聽音樂");
}
@Override
public void via_internet() {
System.out.println("用Android手機上網");
}
}
實現產品類3:Windows Phone,雲集當前三大流行機型
package com.loulijun.chapter8;
public class WindowsPhone extends Phone {
@Override
public void call() {
System.out.println("用windows phone手機打電話");
}
@Override
public void music() {
System.out.println("用windows phone手機聽音樂");
}
@Override
public void via_internet() {
System.out.println("用windows phone手機上網");
}
}
抽象一個富士康(富士康是代工廠嘛)
package com.loulijun.chapter8;
//抽象類,抽象富士康
public abstract class AbstractFoxconn {
/**
* 這裡采用泛型對createPhone的輸入參數產生顯示
* 1、輸入參數必須是Class類型
* 2、輸入參數必須是Phone的實現類
*/
public abstract <T extends Phone> T createPhone(Class<T> c);
}
實現抽象類
package com.loulijun.chapter8;
//實現類,富士康工廠
public class Foxconn extends AbstractFoxconn {
@Override
public <T extends Phone> T createPhone(Class<T> c) {
//定義一個手機
Phone phone = null;
try
{
//生產一個手機
phone = (Phone)Class.forName(c.getName()).newInstance();
}catch(Exception e)
{
e.printStackTrace();
}
return (T)phone;
}
}
場景類,深圳
package com.loulijun.chapter8;
//場景類,深圳的富士康代工生產各種系統的手機
public class Shenzhen {
public static void main(String args[])
{
//富士康
AbstractFoxconn foxconn = new Foxconn();
//生產iphone
System.out.println("----------生產一部iphone----------");
Phone iphone = foxconn.createPhone(iPhone.class);
iphone.call();
iphone.music();
iphone.via_internet();
//生產AndroidPhone
System.out.println("----------生產一部AndroidPhone,如htc的----------");
Phone androidphone = foxconn.createPhone(AndroidPhone.class);
androidphone.call();
androidphone.music();
androidphone.via_internet();
}
}
運行結果:
----------生產一部iphone----------
用iphone打電話
用iphone聽音樂
用iphone上網
----------生產一部AndroidPhone,如htc的----------
用Android手機打電話
用Android手機聽音樂
用Android手機上網
這樣一個完成的工場方法模式就結束了,當然具體怎麼用,怎麼擴展就要根據實際項目來操作了
工場方法模式的優缺點可以參考:http://blog.csdn.net/beyondhaven/article/details/6948067
工場方法模式可以有很多中變換,可以是簡單工場方法模式,可以是多工場方法模式,可以替換單例模式等等
簡單工場方法模式:
不需要抽象工場類,並且createPhone方法時static (靜態)的
多工場方法模式:
通過繼承基抽象工場細分不同產品所對應的抽象工場,例如生產iphone、AndoridPhone、WindowsPhone所繼承的工場分別是三個不同的繼承自AbstractFoxconn的不同抽象工場,然後在場景類中根據具體需求選擇需要使用的抽象工場
摘自 花郎