一 简介

1.1 叙述

1)在Java当中,万物皆为对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重。假如我们需要更换对象,所有new对象的地方都需要修改一遍,这显然是违背了软件设计的开闭原则。
2)如果我们使用工厂来生产该对象,那么我们就只要和工厂打交道就可以了。彻底和对象进行解耦,如果需要更换对象,那么直接在工厂里面更换该对象即可。达到了与对象解耦的目的,所以说,工厂模式的最大优点就是:解耦。

1.2 三种模式

这里会介绍三种工厂模式:
1)简单工厂模式(这个不属于23种设计模式里面)
2)工厂方法模式
3)抽象工厂模式

二 简单工厂模式

简单工厂不是一种设计模式,反而比较像是一种编程习惯。
这种写法,在新增了产品的时候,有两步:
1、新增一个产品实现类,实现接口。
2、修改工厂类,在决定生产产品的方法上修改代码,增加生产该产品的条件

  • Coffee(产品,接口)

    1. public interface Coffee {
    2. String getName();
    3. }
  • AmericanCoffee(具体的产品,类)

    1. public class AmericaCoffee implements Coffee {
    2. @Override
    3. public String getName() {
    4. return "America Coffee";
    5. }
    6. }
  • CoffeeFactory(创建者,类)

    1. public class CoffeeFactory {
    2. public static Coffee makeCoffee(int type) {
    3. if (type == 1) {
    4. return new AmericaCoffee();
    5. } else if (type == 2) {
    6. return new ChinaCoffee();
    7. } else {
    8. throw new RuntimeException("error");
    9. }
    10. }
    11. public static void main(String[] args) {
    12. Coffee coffee = CoffeeFactory.makeCoffee(1);
    13. System.out.println(coffee.getName());
    14. }
    15. }

    在开发中将工厂类中的创建对象的功能方法定义为静态的,这就是静态工厂模式,这个也不属于23种设计模式里面的。

    三 工厂方法模式

    1)简单工厂模式它也违背了开闭原则, 如果我们需要新增Coffee的种类的话,那么我们还是需要修改工厂类CoffeeFactory这个类
    2)我们对上一种简单工厂模式进行修改,因为在扩展其他品种的Coffee时,需要修改CoffeFacoty这个类,那么我们就可以将CoffeeFactory这个类设置为抽象类,然后取每一种Coffee一种Factory,这样子在扩展其他品种的时候,只需要新增两个类,一个Coffee类,一个Coffee对应的Factory类。

  • CoffeeFactory

    1. public interface CoffeFactory {
    2. public Coffee createCoffee();
    3. }
  • LatteCoffee

    1. public class LatteCoffeeFactory implements CoffeFactory {
    2. @Override
    3. public Coffee createCoffee() {
    4. return new LatteCoffee();
    5. }
    6. }
  • CoffeStore

    1. public class CoffeStore {
    2. private CoffeFactory factory;
    3. // 设置Coffee工厂
    4. public void setFactory(CoffeFactory factory) {
    5. this.factory = factory;
    6. }
    7. public Coffee orderCoffee() {
    8. Coffee coffee = this.factory.createCoffee();
    9. return coffee;
    10. }
    11. }

    工厂方法的优缺点
    1)优点:

  • 用户只需要知道具体工厂的名称就可以得到所需要的产品,无需要知道产品的创建过程

  • 在系统增加新的产品的时候,只需要添加具体产品类和对应的具体工厂类,无需要对原工厂进行修改,满足开闭原则

2)缺点

  • 每增加一个产品就需要增加一个产品类和一个对应的具体工厂类,这增加了系统的复杂度。

    四 抽象工厂模式

    1)前面的工厂模式都只考虑生产一种产品,如果Coffee工厂只生产Coffee,Tea工厂只生产Tea。
    2)也就是说工厂方法模式只考虑生产同一种产品。但是在现实中,工厂一般是综合性的工厂,可以生产很多种类的产品。
    3)抽象工厂模式将解决这个问题,将考虑到生产多等级的产品。

抽象工厂模式一般涉及的类比较多,这里就放在一个代码块中展示

  1. // coffee接口
  2. public interface Coffee {
  3. String getCoffeeName();
  4. }
  5. // 具体需要生产的coffee
  6. public class LatteCoffee implements Coffee {
  7. @Override
  8. public String getCoffeeName() {
  9. return "Latte coffee";
  10. }
  11. }
  12. public class AmericaCoffee implements Coffee {
  13. @Override
  14. public String getCoffeeName() {
  15. return "america coffee";
  16. }
  17. }
  18. // coffee工厂
  19. public interface CoffeeFactory {
  20. Coffee makeCoffee();
  21. }
  22. // 生产具体coffee的工厂
  23. public class LatteCoffeeFactory implements CoffeeFactory{
  24. @Override
  25. public Coffee makeCoffee() {
  26. return new LatteCoffee();
  27. }
  28. }
  29. // milk接口
  30. public interface Milk {
  31. String MilkName();
  32. }
  33. // 需要生产的具体的milk
  34. public class MengNiuMilk implements Milk {
  35. @Override
  36. public String MilkName() {
  37. return "MengNiu milk";
  38. }
  39. }
  40. public class YiliMilk implements Milk {
  41. @Override
  42. public String MilkName() {
  43. return "yili milk";
  44. }
  45. }
  46. // milk工厂
  47. public interface MilkFactory {
  48. Milk makeMilk();
  49. }
  50. // 生产具体的milk的工厂
  51. public class MengNiuMilkFactory implements MilkFactory{
  52. @Override
  53. public Milk makeMilk() {
  54. return new MengNiuMilk();
  55. }
  56. }
  57. // 超级工厂,成产milk,coffee
  58. public class SuperFactory {
  59. private CoffeeFactory coffeeFactory;
  60. private MilkFactory milkFactory;
  61. public Coffee makeCoffee() {
  62. return coffeeFactory.makeCoffee();
  63. }
  64. public Milk makeMilk() {
  65. return milkFactory.makeMilk();
  66. }
  67. public static void main(String[] args) {
  68. SuperFactory superFactory = new SuperFactory();
  69. superFactory.setCoffeeFactory(new LatteCoffeeFactory());
  70. superFactory.setMilkFactory(new MengNiuMilkFactory());
  71. Coffee coffee = superFactory.makeCoffee();
  72. System.out.println(coffee.getCoffeeName());
  73. Milk milk = superFactory.makeMilk();
  74. System.out.println(milk.MilkName());
  75. }
  76. }