目的
定义创建对象的方法/接口,然后让子类来决定创建具体的类的对象。
通过不同的类,使得实例化延迟至子类。
特点
必须引入继承,才能算是工厂方法模式。
Found in JDK API
java.util.Calendar#getInstance()
java.text.NumberFormat#getInstance()
java.lang.StringBuffer, java.lang.StringBuilder(继承自 AbstractStringBuilder)
变种
工厂方法是抽象的;
工厂方法有默认实现;
参数化工厂方法;
去掉Creator/Factory类,直接在类中定义工厂方法。
代码实现
Product是基类,子类包括MyProduct,YourProduct,DefaultProduct。
工厂方法是抽象的
package abs.factory; import abs.domain.Product; public abstract class ProductFactory { public abstract Product createProduct(); } package abs.factory; import abs.domain.MyProduct; import abs.domain.Product; public class MyProductFactory extends ProductFactory { @Override public Product createProduct() { return new MyProduct(); } } package abs.factory; import abs.domain.Product; import abs.domain.YourProduct; public class YourProductFactory extends ProductFactory { @Override public Product createProduct() { return new YourProduct(); } }
客户端调用
ProductFactory mpf = new MyProductFactory(); ProductFactory ypf = new YourProductFactory(); Product mp = mpf.createProduct(); Product yp = ypf.createProduct(); System.out.println(mp); System.out.println(yp);
工厂方法有默认实现
public class ProductFactory { public Product createProduct() { return new MyProduct(); } } public class YourProductFactory extends ProductFactory { @Override public Product createProduct() { return new YourProduct(); } }
客户端调用
ProductFactory pf = new ProductFactory(); ProductFactory ypf = new YourProductFactory(); Product mp = pf.createProduct(); Product yp = ypf.createProduct();
参数化工厂方法
public class ProductFactory { public Product createProduct() { return this.createProduct(null); } public Product createProduct(String productName) { if("my".equals(productName)) { return new MyProduct(); } else if("your".equals(productName)) { return new YourProduct(); } return new DefaultProduct(); } }
客户端调用
ProductFactory pf = new ProductFactory(); Product myProduct = pf.createProduct("my"); Product yourProduct = pf.createProduct("your"); Product defaultProduct = pf.createProduct();
去掉Creator/Factory类,直接在类中定义工厂方法
通常结合静态化的参数化工厂方法的方式来实现
public class Product { protected Product() { } public static Product getInstance() {
return getInstance(null);
} public static Product getInstance(String productName) { if("my".equals(productName)) { return new MyProduct(); } else if("your".equals(productName)) { return new YourProduct(); } return new DefaultProduct(); } }
客户端调用
Product myProduct = Product.getInstance("my"); Product yourProduct = Product.getInstance("your"); Product defaultProduct = Product.getInstance();
JDK API应用场景:java.util.Calendar
public class Calendar {
protected Calendar()
{
this(TimeZone.getDefaultRef(), Locale.getDefault());
sharedZone = true;
}
public static Calendar getInstance() { Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault()); cal.sharedZone = true; return cal; } public static Calendar getInstance(TimeZone zone) { return createCalendar(zone, Locale.getDefault()); } public static Calendar getInstance(Locale aLocale) { Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale); cal.sharedZone = true; return cal; } public static Calendar getInstance(TimeZone zone, Locale aLocale) { return createCalendar(zone, aLocale); } private static Calendar createCalendar(TimeZone zone, Locale aLocale) { // If the specified locale is a Thai locale, returns a BuddhistCalendar // instance. if ("th".equals(aLocale.getLanguage()) && ("TH".equals(aLocale.getCountry()))) { return new sun.util.BuddhistCalendar(zone, aLocale); } else if ("JP".equals(aLocale.getVariant()) && "JP".equals(aLocale.getCountry()) && "ja".equals(aLocale.getLanguage())) { return new JapaneseImperialCalendar(zone, aLocale); } // else create the default calendar return new GregorianCalendar(zone, aLocale); } }