前言
设计模式分为三大类:
创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式;
结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式;
行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式;
简单工厂
首先要明确的是,简单工厂模式不属于23种设计模式,它引入了创建者的概念,将实例化的代码从应用代码中抽离,在工厂类的静态方法中只处理被创建的对象,如果业
务需要变更则需要在工厂类中添加具体的实现类,因此维护性较差。以"工厂创建咖啡"为例说明,如下:
1. 物品标识类Coffee和已有的类
package com.oxygen.bean;/*** * 咖啡则作为一种抽象概念:拿铁、美式咖啡、卡布奇诺等均为咖啡家族的一种产品* @author Oxygen**/ public abstract class Coffee {public abstract String desc(); //获取coffee名称 }class Americano extends Coffee { // 美式咖啡 @Overridepublic String desc() {return "美式咖啡";}}class Cappuccino extends Coffee { //卡布奇诺 @Overridepublic String desc() {return "卡布奇诺";}}class Latte extends Coffee { //拿铁 @Overridepublic String desc() {return "拿铁";}}
2. 简单工厂
package com.oxygen.bean;/*** 创建材料的工厂类* @author Oxygen * @date 2018年10月16日*/ public class SimpleFactory {/*** * @param type 材料类型* @return*/public static Coffee createInstance(String type) {if ("Americano".equals(type)) {return new Americano();} else if ("Cappuccino".equals(type)) {return new Cappuccino();} else if ("Latte".equals(type)) {return new Latte();} else {throw new RuntimeException("type[" + type + "]类型不可识别,没有匹配到可实例化的对象!");}}public static void main(String[] args) {System.out.println(SimpleFactory.createInstance("Americano").desc());System.out.println(SimpleFactory.createInstance("Cappuccino").desc());System.out.println(SimpleFactory.createInstance("Latte").desc());} }
3. 输出结果
美式咖啡
卡布奇诺
拿铁
工厂方法
工厂方法模式其定义了一个创建对象的接口,由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到了子类,也就是说一个工厂只能生成特定的Coffee
1. 工厂类
package com.oxygen.bean;/*** Coffee工厂* @author Oxygen * @date 2018年10月16日*/ public abstract interface CoffeeFactory {public abstract Coffee[] createCoffee();public static void main(String[] args) {CoffeeFactory chinaCoffeeFactory = new ChinaCoffeeFactory();Coffee[] chinaCoffees = chinaCoffeeFactory.createCoffee();System.out.print("中国咖啡工厂可以生产的咖啡有:");print(chinaCoffees);CoffeeFactory americaCoffeeFactory = new AmericaCoffeeFactory();Coffee[] americaCoffees = americaCoffeeFactory.createCoffee();System.out.print("美国咖啡工厂可以生产的咖啡有:");print(americaCoffees);}public static void print(Coffee[] c) {for (Coffee coffee : c) {System.out.print(coffee.desc() + " ");}System.out.println();} }class ChinaCoffeeFactory implements CoffeeFactory { //中国咖啡工厂 @Overridepublic Coffee[] createCoffee() {return new Coffee[] { new Cappuccino(), new Latte() };}}class AmericaCoffeeFactory implements CoffeeFactory { //美国咖啡工厂 @Overridepublic Coffee[] createCoffee() {return new Coffee[] { new Americano(), new Latte() };}}
2. 输出结果
中国咖啡工厂可以生产的咖啡有:卡布奇诺 拿铁
美国咖啡工厂可以生产的咖啡有:美式咖啡 拿铁
抽象工厂
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类,在上述的场景上继续延伸:咖啡工厂做大做强,引入了新的饮品种类:茶、 碳酸饮
料。中国工厂只能制造咖啡和茶,美国工厂只能制造咖啡和碳酸饮料,如果继续使用上述工厂方法方式,除去对应的产品实体类还需要新增2个抽象工厂(茶制造
工厂、碳酸饮料制造工厂),4个具体工厂实现。
随着产品的增多,会导致类爆炸,这显然是不能接受的。所以这里引出一个概念产品家族,在此例子中,不同的饮品就组成我们的饮品家族, 饮品家族开始承担
创建者的责任,负责制造不同的产品。如下:
package com.oxygen.bean;public interface AbstractDrinksFactory {Coffee createCoffee(); //制造咖啡 Tea createTea(); //制造茶 Sodas createSodas();//制造碳酸饮料 }/*** 中国饮品工厂:制造咖啡与茶*/ class ChinaDrinksFactory implements AbstractDrinksFactory {@Overridepublic Coffee createCoffee() {return new Latte();}@Overridepublic Tea createTea() {return new MilkTea();}@Overridepublic Sodas createSodas() {// TODO Auto-generated method stubreturn null;} }/*** 美国饮品制造工厂:制造咖啡和碳酸饮料*/ class AmericaDrinksFactory implements AbstractDrinksFactory {@Overridepublic Coffee createCoffee() {// TODO Auto-generated method stubreturn new Latte();}@Overridepublic Tea createTea() {// TODO Auto-generated method stubreturn null;}@Overridepublic Sodas createSodas() {// TODO Auto-generated method stubreturn new CocaCola();}}
总结
工厂模式可以帮助我们针对抽象接口编程,而不是针对具体类编程,在不同的场景下按具体情况来
1. 简单工厂:不能算是真正意义上的设计模式,但可以将客户程序从具体类解耦;
2. 工厂方法:使用继承,把对象的创建委托给子类,由子类来实现创建方法,可以看作是抽象工厂模式中只有单一产品的情况;
3. 抽象工厂:使对象的创建被实现在工厂接口所暴露出来的方法中;