详解设计模式 - 工厂模式(3种)

详解设计模式 - 工厂模式(3种)

2018-10-20 23:45:00 设计模式 19 0

这篇文章作为个人学习备忘笔记,通过生活中的牛奶工厂实例,比对3种工厂模式的不同。

工厂模式一句话总结:

只对生产结果负责,不要三无产品。

生活中的工厂例子

  • 小作坊:五花八门什么都能生产,但生产质量和产品种类不一定满足消费者的需求。
  • 专业工厂:遵循一定标准,不生产其他产品,只专注于自己的产品,不断精益求精。
  • 大型国际工厂:专业、高效,无论是产品质量还是产品种类,都能让用户放心。

以上这三种工厂,对应到设计模式中分别就是:简单工厂模式工厂方法模式抽象工厂模式。 < !-- more -->

牛奶工厂案例

有三种牛奶:蒙牛、伊利、特仑苏,现在分不同的工厂去生产。

牛奶(它是一个抽象的东西)
/**
 * 牛奶
 *
 * @author Zebe
 */
public interface Milk {

    /**
     * 牛奶名称
     * @return 返回牛奶名称
     */
    String getName();

}
蒙牛
/**
 * 蒙牛牛奶
 *
 * @author Zebe
 */
public class MengNiu implements Milk {

    @Override
    public String getName() {
        return "蒙牛";
    }
}
伊利
/**
 * 伊利牛奶
 *
 * @author Zebe
 */
public class YiLi implements Milk {

    @Override
    public String getName() {
        return "伊利";
    }
}
特仑苏
/**
 * 特仑苏牛奶
 *
 * @author Zebe
 */
public class TeLunSu implements Milk {

    @Override
    public String getName() {
        return "特仑苏";
    }
}

简单工厂模式的做法

用户要什么就给什么,如果自己没有的,就给不了。

/**
 * 简单工厂(很少使用)
 *
 * 说明:这是简单工厂模式(根据用户要求来,不一定完全满足用户的需要)
 *
 * @author Zebe
 */
public class SimpleFactory {

    /**
     * 生产牛奶
     * @param name 牛奶名称
     * @return 根据牛奶名称返回具体的牛奶
     */
    Milk getMilk(String name) {
        if ("蒙牛".equals(name)) {
            return new MengNiu();
        } else if ("伊利".equals(name)) {
            return new YiLi();
        } else if ("特仑苏".equals(name)) {
            return new TeLunSu();
        } else {
            // 如果要新增加一种牛奶,必须修改这里的代码实现
            System.out.println("无法生成指定的牛奶:" + name);
            return null;
        }
    }

}
使用测试
/**
 * 简单工厂使用测试
 *
 * @author Zebe
 */
public class SimpleFactoryTest {

    /**
     * 程序入口
     * @param args 运行参数
     */
    public static void main(String[] args) {
        SimpleFactory factory = new SimpleFactory();
        // 这里如果名称传错,会得不到想要的牛奶
        System.out.println(factory.getMilk("蒙牛"));
    }

}

工厂方法模式的做法

指定一个协议(标准),所有牛奶工厂都要遵循这个协议来生产。

/**
 * 牛奶工厂(更加专业,不同的工厂只生产指定的牛奶)
 *
 * 说明:这是工厂方法模式(相当于制定一个加工协议或者标准,其他的牛奶工厂都要按照这个协议去实现)
 *
 * @author Zebe
 */
public interface SpecificMilkFactory {

    /**
     * 生产牛奶(这是一个协议)
     * @return 返回牛奶
     */
    Milk getMilk();

}
蒙牛工厂(按协议来生产)
/**
 * 蒙牛工厂(只专注于生产蒙牛牛奶)
 *
 * @author Zebe
 */
public class MengNiuFactory implements SpecificMilkFactory {

    @Override
    public Milk getMilk() {
        return new MengNiu();
    }
}
伊利工厂(按协议来生产)
/**
 * 伊利工厂(只专注于生产伊利牛奶)
 *
 * @author Zebe
 */
public class YiLiFactory implements SpecificMilkFactory {

    @Override
    public Milk getMilk() {
        return new YiLi();
    }
}

特仑苏工厂(按协议来生产)
/**
 * 特仑苏工厂(只专注于生产特仑苏牛奶)
 *
 * @author Zebe
 */
public class TeLunSuFactory implements SpecificMilkFactory {

    @Override
    public Milk getMilk() {
        return new TeLunSu();
    }
}
使用测试
/**
 * 牛奶工厂测试
 *
 * @author Zebe
 */
public class SpecificMilkFactoryTest {

    /**
     * 运行入口
     *
     * @param args 运行参数
     */
    public static void main(String[] args) {
        // 要什么牛奶,就需要指定具体某个专业的牛奶工厂
        SpecificMilkFactory factory = new MengNiuFactory();
        System.out.println(factory.getMilk());
    }

}

抽象工厂模式的做法

更专业、质量更高,对于生产的产品有明确规范,除了能自己生产,还可以委派给其他专业的牛奶工厂生产(国内或者国外都行)。

/**
 * 牛奶工厂(高级流水线工厂)
 * 说明:这是抽象工厂模式(把所有能生产的牛奶抽象出来)
 *
 * @author Zebe
 */
public abstract class AbstractMilkFactory {

    /**
     * 生产蒙牛牛奶
     * @return 返回蒙牛牛奶
     */
    abstract Milk getMengNiu();

    /**
     * 生产伊利牛奶
     * @return 返回伊利牛奶
     */
    abstract Milk getYiLi();

    /**
     * 生产特仑苏牛奶
     * @return 返回特仑苏牛奶
     */
    abstract Milk getTeLunSu();

}
具体的某某牛奶工厂
/**
 * 某某牛奶工厂(可以生产所有牛奶)
 *
 * @author Zebe
 */
public class XXXMilkFactory extends AbstractMilkFactory {

    @Override
    Milk getMengNiu() {
        // 自己生产
        return new MengNiu();
        // 或委派给专业的蒙牛工厂生产(混用设计模式)
        // return new MengNiuFactory().getMilk();
    }

    @Override
    Milk getYiLi() {
        // 自己生产
        return new YiLi();
        // 或委派给专业的伊利工厂生产(混用设计模式)
        // return new YiLiFactory().getMilk();
    }

    @Override
    Milk getTeLunSu() {
        // 自己生产
        return new TeLunSu();
        // 或委派给专业的特仑苏工厂生产(混用设计模式)
        // return new TeLunSuFactory().getMilk();
    }
}
使用测试
/**
 * 牛奶工厂测试
 *
 * @author Zebe
 */
public class AbstractMilkFactoryTest {

    /**
     * 运行入口
     *
     * @param args 运行参数
     */
    public static void main(String[] args) {
        XXXMilkFactory factory = new XXXMilkFactory();
        // 用户想要什么牛奶,应有尽有
        System.out.println(factory.getMengNiu());
        System.out.println(factory.getYiLi());
        System.out.println(factory.getTeLunSu());
        // 假设这个牛奶工厂出新产品了,例如:莫斯利安
        // 那么用户只需要拿钱购买即可(客户端不做改变),如下:
        // System.out.println(factory.getMoSiLiAn());
    }

}

小结

1、小作坊(简单工厂模式)明显不可靠,所以很少使用或者不使用。 2、工厂方法模式可以看成就是一个协议(接口),对应所有的具体工厂都要遵循这个协议来进行生产。 3、抽象工厂模式是最可靠的工厂模式,它最大程度地屏蔽了生产细节

赞赏支持!
设计模式工厂模式简单工厂模式工厂方法模式抽象工厂模式
上一篇:SpringBoot开启Tomcat访问日志access-log 下一篇:Java - 局部变量和StackOverflowError

文章评论

欢迎一起交流

评论框加载中......