设计模式从入门到放弃(三)工厂模式

设计模式从入门到放弃(三)工厂模式

基本介绍

  • 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式
  • 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
  • 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.

简单工厂模式

设计模式从入门到放弃(三)工厂模式_第1张图片

从上面的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(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

设计模式从入门到放弃(三)工厂模式_第2张图片

代码演示

// 不同产地的披萨 拿一个为例 其他类似
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;
}


你可能感兴趣的:(设计模式)