设计模式:创建型模式:工厂模式

205 阅读3分钟

不使用工厂模式时

  1. 当我们想设计一个商店类,它可以卖牙膏,我们需要根据不同的牙膏品牌判断, 生产不同的牙膏
/**
 * 购物网站类用于用户消费者购买牙膏
 */
public class Shop {
    /**
     * 销售牙膏方法
     */
    public Toothpaste sellToothpaste(String brand) {
        Toothpaste toothpaste = null;
        if ("中华牌".equals(brand)) {
            toothpaste = new ZhongHuaToothpaste();
        } else if ("高露洁牌".equals(brand)) {
            toothpaste = new GaoLuJieToothpaste();
        } else if ("佳洁士".equals(brand)) {

        } else {
            //提示错误或者抛异常
        }
        toothpaste.createPaste();
        toothpaste.createShell();
        toothpaste.pack();
        return toothpaste;
    }
}

  1. 以上设计违反了开闭原则,一旦需要增加新的牙膏品牌就需要修改shop类。

使用简单工厂模式(静态工厂模式)

  1. 对于 shop 类而言,它只应该负责卖牙膏,而不负责生产牙膏,否则就违背的职责单一原则。
  2. 所以我们可以通过 简单工厂类 来创建牙膏, 解除了 shop和具体牙膏 的耦合。

3. 简单工厂将 被使用方(具体产品) 的创建过程,封装到一个工厂类中,这样就在 使用方 和 被使用方 之间做了一个缓冲,降低了使用方和被使用方的耦合度。 4. 但是 简单工厂类对象 还是违背了 开闭原则,但更好的实现了 职责单一原则。 5. 所以简单工厂适用于 具体对象(即实现类个数)稳定,不太经常新增或修改。

/**
 * 用于生产牙膏的简单工厂
 */
public class ToothpasteFactory {
    /**
     * 创建牙膏方法
     *
     * @param brand
     * @return
     */
    public static Toothpaste createToothpaste(String brand) {

        Toothpaste toothpaste = null;

        if ("中华牌".equals(brand)) {
            toothpaste = new ZhongHuaToothpaste();
        } else if ("高露洁牌".equals(brand)) {
            toothpaste = new GaoLuJieToothpaste();
        }

        toothpaste.createPaste();
        toothpaste.createShell();
        toothpaste.pack();

        return toothpaste;
    }
}


/**
 * 商店类用于用户消费者购买牙膏
 * @author Peter
 */
public class Shop {
	/**
	 * 卖牙膏方法
	 */
	public Toothpaste sellToothpaste(String brand){
		return SimpleFactory.createToothpaste(brand);
	}
}

工厂方法模式

  1. 为了解决 简单工厂的不可拓展问题,引出可工厂方法模式。
  2. 工厂方法模式将提供工厂的抽象类或接口,生产抽象产品,由一个个具体的工厂类来提供实现。

/**
 * 工厂的抽象类,依赖于 抽象的产品 类
 */
public interface ToothpasteFactory {
    Toothpaste create();
}


/**
 * 具体产品的工厂, 高露洁工厂
 */
public class GaoLuJieFactory implements ToothpasteFactory {

    public Toothpaste create() {
        return new GaoLuJieToothpaste("高露洁");
    }
}

/**
 * 具体的工厂类,生产佳洁士牙膏
 */
public class JiaJieShiFactory implements ToothpasteFactory {
    public Toothpaste create() {
        return new JiaJieShiToothpaste("佳洁士");
    }
}

/**
 * 使用类只接收工厂的抽象类,并且返回产品的抽象产品
 */
public class Shop {
    /*
     * 销售牙膏
     */
    public Toothpaste sellToothpaste(ToothpasteFactory toothpasteFactory) {
        return toothpasteFactory.create();
    }
}

抽象工厂模式

  1. 工厂方法模式,只能生产一种产品,而不能生产多种类型的产品。
  2. 此时,就需要引入 抽象工厂模式。
  3. 如果要生产一系列的产品,就需要抽象工厂模式。
  4. 抽象工厂模式就是把多个工厂方法模式整合起来。
  5. 使用抽象工厂生产的产品必须是一系列 有联系的 产品。
  6. 不同的产品 必须是同一个 工厂生产。(如高露洁工厂 可以生产 牙膏和牙刷)
  7. 其目的是生产一系列的产品、或者是 产品蔟。

/**
抽象工厂类, 可以生产产品蔟
**/
public interface ToothUtilFactory {

    /**
     * 创建牙膏方法
     * @return
     */
    Toothpaste createToothpaste();

    /**
    * 创建牙刷方法
    * @return
    */
    Toothbrush createToothbrush();
}


/**
 * 实现类,中华牌牙具工厂类
 * @author Peter
 */
public class ZhongHuaFactory  implements ToothUtilFactory {

    // 生产牙膏
    @Override
    public Toothpaste createToothpaste() {
        Toothpaste toothpaste=new ZhongHuaToothpaste();
        toothpaste.createPaste();
        toothpaste.createShell();
        toothpaste.pack();
        return toothpaste;
    }
    
    // 生产牙刷
    @Override
    public Toothbrush createToothbrush() {
        Toothbrush toothbrush=new ZhongHuaToothbrush();
        toothbrush.createHandle();
        toothbrush.createHair();
        toothbrush.pack();
        return toothbrush;
    }
}

工厂模式在典型框架中的应用

  1. 工厂方法模式 Spring的BeanFactory 接口, 其将创建返回什么样的对象,下沉到具体的工厂子类去实现。
  2. 抽象工厂模式 Spring的 ApllicationContext 对象,返回了多个 实现了 BeanFactory 对象的接口。