工厂方法模式定义: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的不同抽象工场,然后在场景类中根据具体需求选择需要使用的抽象工场
|