简单工厂模式

传统方式的优缺点: 1、优点是比较好理解,简单易操作 2、缺点是违反了设计模式的ocp原则,当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码

基本介绍:
1、简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单使用的模式
2、定义了一个创建对象的类,由这个类来封装实例化对象的行为
3、在软件开发中,当我们需要大量的创建某种、某类或某批对象时,就会使用到工厂模式
例如有一个电脑工厂,生产惠普和华硕2中品牌

  1. public abstract class Computer {
  2. private String name;
  3. /**
  4. * 启动
  5. */
  6. public abstract void startup();
  7. public void setName(String name){
  8. this.name=name;
  9. }
  10. }
  1. public class HpComputer extends Computer {
  2. @Override
  3. public void startup() {
  4. System.out.println("启动惠普");
  5. }
  6. }
  1. public class HuashuoComputer extends Computer {
  2. @Override
  3. public void startup() {
  4. System.out.println("启动华硕");
  5. }
  6. }

现在创建一个电脑工厂,这里创建实例用的是静态方法

  1. public class ComputerFactory {
  2. public static Computer createComputer(String name){
  3. Computer computer = null;
  4. switch (name){
  5. case "hp":
  6. computer = new HpComputer();
  7. computer.setName(name);
  8. break;
  9. case "huashuo":
  10. computer = new HuashuoComputer();
  11. computer.setName(name);
  12. break;
  13. default:
  14. System.out.println("品牌有误");
  15. }
  16. return computer;
  17. }
  18. }

然后可以通过电脑工厂来调用

  1. public static void main(String[] args) {
  2. Computer hp = ComputerFactory.createComputer("hp");
  3. hp.startup();
  4. Computer huashuo = ComputerFactory.createComputer("huashuo");
  5. huashuo.startup();
  6. }

工厂方法模式

工厂方法模式定义了一个创建对象的抽象方法,由子类决定要实例化的类,它将对象的实例化推迟到子类
简单的讲,就是在简单工厂方法模式上再加一层。将上述的工厂类改为抽象类,里面写抽象方法,方法是实现推迟到子类,这里方法的实现就是对象的实例化。
UML类图如下:
image-20210329143427904.png
模式组成:

组成(角色) 关系 作用
抽象产品(Product) 具体的产品关系 描述具体产品的公共接口
具体产品(Concrete Product) 抽象产品的子类:工厂类创建的目标类 描述生产的具体产品
抽象工厂(Creator) 具体工厂的父类 描述工厂的公共接口
具体工厂(Concrete Creator) 抽象工厂的子类;被外界调用 描述具体工厂;实现FactoryMethod工厂方法创建产品的实例

抽象工厂模式

基本介绍:
1、定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类
2、抽象工厂可以将简单工厂模式和工厂方法模式进行整合
3、从设计层面看,抽象工厂模式就是对简单工厂模式的改进(进一步的抽象)
4、将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类。可以根据创建对象类型使用对应的工厂子类,这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展
下面有示例,一个卖Pizza的例子。
image-20210327133324265.png
AbsFactory接口作为抽象工厂,它有两个实现类,各种订单需求直接调用接口即可。
代码示例:
抽象类Pizza,及其2个抽象子类,4个实现类

  1. public abstract class Pizza {
  2. /**
  3. * 准备Pizza
  4. */
  5. public abstract void prepare();
  6. public void bake(){
  7. System.out.println("烘焙");
  8. }
  9. public void cut(){
  10. System.out.println("切");
  11. }
  12. public void box(){
  13. System.out.println("烤");
  14. }
  15. }
  16. public abstract class BJPizza extends Pizza{
  17. }
  18. public abstract class LDPizza extends Pizza {
  19. }
  20. public class BJCheesePizza extends BJPizza {
  21. @Override
  22. public void prepare() {
  23. System.out.println("准备北京奶酪Pizza");
  24. }
  25. }
  26. public class BJPepperPizza extends BJPizza{
  27. @Override
  28. public void prepare() {
  29. System.out.println("准备北京胡椒Pizza");
  30. }
  31. }
  32. public class LDCheesePizza extends LDPizza{
  33. @Override
  34. public void prepare() {
  35. System.out.println("准备伦敦奶酪Pizza");
  36. }
  37. }
  38. public class LDPepperPizza extends LDPizza {
  39. @Override
  40. public void prepare() {
  41. System.out.println("准备伦敦胡椒Pizza");
  42. }
  43. }

抽象工厂接口及其两个实现类

  1. public interface AbsFactory {
  2. /**
  3. * 制作Pizza
  4. * @param name
  5. * @return Pizza
  6. */
  7. Pizza createPizza(String name);
  8. }
  9. public class BJFactory implements AbsFactory {
  10. @Override
  11. public Pizza createPizza(String name) {
  12. switch (name){
  13. case "cheese":
  14. return new BJCheesePizza();
  15. case "pepper":
  16. return new BJPepperPizza();
  17. default:
  18. return null;
  19. }
  20. }
  21. }
  22. public class LDFactory implements AbsFactory {
  23. @Override
  24. public Pizza createPizza(String name) {
  25. switch (name){
  26. case "cheese":
  27. return new LDCheesePizza();
  28. case "pepper":
  29. return new LDPepperPizza();
  30. default:
  31. return null;
  32. }
  33. }
  34. }

调用工厂接口

  1. public class OrderPizza {
  2. public static Pizza createPizza(AbsFactory absFactory,String name){
  3. return absFactory.createPizza(name);
  4. }
  5. public static void main(String[] args) {
  6. createPizza(new BJFactory(),"cheese").prepare();
  7. createPizza(new BJFactory(),"pepper").prepare();
  8. createPizza(new LDFactory(),"cheese").prepare();
  9. createPizza(new LDFactory(),"pepper").prepare();
  10. }
  11. }

调用结果

  1. 准备北京奶酪Pizza
  2. 准备北京胡椒Pizza
  3. 准备伦敦奶酪Pizza
  4. 准备伦敦胡椒Pizza

工厂模式在JDK-Calender应用:JDK中的Calendar类中,就使用了简单工厂模式

  • 工厂模式的意义:将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦,从而提高项目的扩展性和维护性
  • 三种工厂模式:
    • 简单工厂模式(静态工厂模式)
    • 工厂方法模式
    • 抽象工厂模式
  • 对比工厂方法模式与抽象工厂模式
    | 工厂方法模式 | 抽象工厂模式 | | —- | —- | | 针对的是一个产品等级结构 | 针对的是面向多个产品等级结构 | | 一个抽象产品类 | 多个抽象产品类 | | 可以派生出多个具体产品类 | 每个抽象产品类都可以派生出多个具体产品类 | | 一个抽象工厂类,可以派生出多个具体工厂类 | 一个抽象工厂类,可以派生出多个具体工厂类 | | 每个具体工厂类只能创建一个具体产品类的实例 | 每个具体工厂类可以创建多个具体产品类的实例 |

  • 设计模式的依赖抽象原则:

    • 创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回。换种说法,变量不要直接持有具体类的引用。
    • 不要让类继承具体类,而是继承抽象类或者是实现接口
    • 不要覆盖基类中已经实现的方