从上面的UML图可以观察到 Pizza 作为抽象产品提供3个制作披萨的抽象方法 MeatPizza FruitPizza CheesePizza是具体的实现
通过SimplePizzaFactory 传入create(String type) 来区分到底需要创建哪一种披萨
具体代码实现
public interface Pizza {
public void prepare();
public void bake();
public void cut();
public void box();
}
public class MeatPizza implements Pizza {
@Override
public void prepare() {
System.out.println("开始准备肉类披萨");
}
@Override
public void bake() {
System.out.println("开始烘焙肉类披萨");
}
@Override
public void cut() {
System.out.println("开始将肉类披萨分块");
}
@Override
public void box() {
System.out.println("开始打包肉类披萨");
}
}
public class FruitPizza implements Pizza {
@Override
public void prepare() {
System.out.println("开始准备水果披萨");
}
@Override
public void bake() {
System.out.println("开始烘焙水果披萨");
}
@Override
public void cut() {
System.out.println("开始将水果披萨分块");
}
@Override
public void box() {
System.out.println("开始打包水果披萨");
}
}
public class SimplePizzaFactory {
public Pizza create(String pizzaType) {
switch (pizzaType) {
case "meat":
return new MeatPizza();
case "fruit":
return new FruitPizza();
case "cheese":
return new CheesePizza();
default:
return null;
}
}
public void order (String type){
Pizza pizza = create(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
public static void main(String[] args) {
SimplePizzaFactory simplePizzaFactory = new SimplePizzaFactory();
simplePizzaFactory.order("meat");
System.out.println("=============");
simplePizzaFactory.order("fruit");
System.out.println("=============");
simplePizzaFactory.order("cheese");
}
}
核心方法是SimplePizzaFactory中的create方法直接决定了最终生产的产品的形态
随着需求的增加,简单工厂模式已经无法满足我们的需求,现在客户需要在披萨的口味的基础之上要求披萨的产地,上面的简单工厂模式不太好扩展,引出了抽象工厂模式。
我们将工厂再抽象一个高层用于表示披萨不同的产地
将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
// 不同产地的披萨 拿一个为例 其他类似
public class BJFruitPizza extends FruitPizza {
@Override
public void prepare() {
printFrom();
super.prepare();
}
@Override
public void bake() {
printFrom();
super.bake();
}
@Override
public void cut() {
printFrom();
super.cut();
}
@Override
public void box() {
printFrom();
super.box();
}
private void printFrom(){
System.out.println("产地在北京");
}
}
// 抽象工厂类
public interface AbstractFactory {
Pizza createPizza(String type);
}
// 北京披萨工厂
public class BJPizzaFactory implements AbstractFactory {
@Override
public Pizza createPizza(String type) {
if("meat".equals(type)){
return new BJMeatPizza();
}else if("fruit".equals(type)){
return new BJFruitPizza();
}
return null;
}
}
// 重庆披萨工厂
public class CQPizzaFactory implements AbstractFactory {
@Override
public Pizza createPizza(String type) {
if("meat".equals(type)){
return new CQMeatPizza();
}else if("fruit".equals(type)){
return new CQFruitPizza();
}
return null;
}
}
// 测试
public class AbstractFactoryTest {
public static void main(String[] args) {
PizzaStore pizzaStore = new PizzaStore();
AbstractFactory bjPizzaFactory = new BJPizzaFactory();
// 生成北京的水果披萨
pizzaStore.order(bjPizzaFactory.createPizza("fruit"));
System.out.println();
// 生成重庆的肉披萨
AbstractFactory cqPizzaFactory = new CQPizzaFactory();
pizzaStore.order(cqPizzaFactory.createPizza("meat"));
}
}
工厂模式使用广泛例如Spring 的 BeanFactory JDK 的Calendar,Proxy.newInstance
BeanFactory 为顶级的Bean工厂抽象 下面有ListableBeanFactory,HierarchicalBeanFactory等进一步的抽象工厂每种工厂有不同的特性到最终我们使用的ClassPathXmlApplicationContext或者FileSystemXmlApplicationContext等中间经过了多次的抽象。
Calendar的工厂模式就简单一些
Calendar cal = Calendar.getInstance();
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
}
Calendar cal = null;
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
// 根据不同的类型 返回不同的Calendar 对象
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// 根据不同的类型 确定calendar对象
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}
etLanguage() == “ja”
&& aLocale.getCountry() == “JP”) {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}