JavaRush /Java 博客 /Random-ZH /工厂设计模式

工厂设计模式

已在 Random-ZH 群组中发布
朋友你好!今天我们继续和大家一起学习设计模式。在本次讲座中,我们将讨论工厂。我们将与您讨论使用此模板解决了哪些问题,并查看工厂如何帮助开设咖啡店的示例。我还将为您提供创建工厂的 5 个简单步骤。 工厂设计模式 - 1为了与大家达成一致并轻松掌握本质,您应该熟悉以下主题:
  • Java中的继承
  • Java 中引用类型的缩小和扩展
  • 不同类和对象之间的交互

什么是工厂?

工厂设计模式允许您控制对象的创建。创建一个新对象的过程并不那么简单,但也不是太复杂。我们都知道,要创建一个新对象,我们必须使用new. 看起来这里没有什么可管理的,但事实并非如此。当我们的应用程序具有某个具有许多后代的类,并且需要根据某些条件创建某个类的实例时,可能会出现困难。 工厂是一种设计模式,有助于解决根据某些条件创建不同对象的问题。抽象的,不是吗?当我们看下面的例子时,会显得更加具体和清晰。

我们创造不同类型的咖啡

假设我们想要实现一家咖啡店的自动化。我们需要学习如何准备不同类型的咖啡。为此,在我们的应用程序中,我们将创建一个咖啡类及其衍生品:美式咖啡、卡布奇诺、浓缩咖啡、拿铁 - 我们将准备的这些类型的咖啡。我们先从一般的咖啡类开始:
public class Coffee {
    public void grindCoffee(){
        // перемалываем кофе
    }
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
接下来,让我们创建它的继承人:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
我们的客户将订购某种类型的咖啡,并且需要将此信息传递给程序。这可以通过不同的方式完成,例如使用String. 但它最适合这些目的enum。让我们enum在其中创建并定义我们接受订单的咖啡类型:
public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
太好了,现在让我们为我们的咖啡店编写代码:
public class CoffeeShop {

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucсino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
该方法orderCoffee可以分为两个部分:
  1. 在块中创建特定的咖啡实例switch-case。工厂所做的就是根据条件创建特定类型。
  2. 准备工作本身就是研磨、烹饪并倒入杯子中。
如果您将来需要更改该方法,需要了解以下重要信息:
  1. 准备算法本身(研磨、烹饪和倒入杯子)将保持不变(至少我们希望如此)。
  2. 但咖啡的范围可能会改变。也许我们会开始制作摩卡..摩卡..摩卡奇...上帝保佑他,一种新型咖啡。
我们已经可以假设,在未来,以一定的概率,我们将不得不对方法、块进行更改switch-case。也有可能在我们的咖啡店里,这种方法orderCoffee并不是我们制作不同类型咖啡的唯一地方。因此,必须在多个地方进行更改。你可能已经明白我的意思了。我们需要重构。将负责制作咖啡的块移到一个单独的类中有两个原因:
  1. 我们将能够在其他地方重用创建咖啡的逻辑。
  2. 如果范围发生变化,我们将不必在使用咖啡创建的所有地方编辑代码。仅在一处更改代码就足够了。
换句话说,是时候削减工厂了。

我们正在锯切我们的第一家工厂

为此,我们创建一个新类,该类仅负责创建咖啡类的必要实例:
public class SimpleCoffeeFactory {
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        return coffee;
    }
}
恭喜!我们刚刚以最简单的形式实现了工厂设计模式。尽管如果将该方法设为createCoffee静态,一切都会变得更加简单。但这样我们就会失去两种可能性:
  1. 继承SimpleCoffeeFactory并覆盖createCoffee.
  2. 在我们的类中实现所需的工厂实现。
说到实施。我们需要回到咖啡店并实施我们的咖啡制作工厂。

将工厂引入咖啡店

让我们使用工厂重写我们的咖啡厅类:
public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
伟大的。现在让我们尝试示意性地、简洁地描述一下工厂设计模式的结构。

开设自己的工厂的 5 个步骤

步骤 1. 在您的程序中,您有一个具有多个后代的类,如下图所示: 工厂设计模式 - 2步骤 2. 创建一个类enum,在其中为每个后代类定义一个枚举变量:
enum CatType {
    LION,
    TIGER,
    BARSIK
}
第 3 步:建造工厂。你调用它MyClassFactory,代码如下:
class CatFactory {}
步骤 4. 在工厂中创建一个createMyClass采用变量 - 的方法enum MyClassType。代码如下:
class CatFactory {
    public Cat createCat(CatType type) {

    }
}
步骤 5. 在方法主体中编写一个块,switch-case在该块中迭代所有枚举值并创建与该enum值对应的类的实例:
class CatFactory {
        public Cat createCat(CatType type) {
            Cat cat = null;

            switch (type) {
                case LION:
                    cat =  new Barsik();
                    break;
                case TIGER:
                    cat = new Tiger();
                    break;
                case BARSIK:
                    cat =  new Lion();
                    break;
            }

            return cat;
        }
    }
像一个老板一样。

如何训练

读书很好,写代码更棒。如果您的名字有偶数个字母,请尝试创建您自己的虚拟比萨店。如果您的名字有奇数个字母,请尝试创建一个虚拟寿司吧。如果您是匿名的,那么您很幸运。今天你可以休息了。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION