朋友你好!今天我们继续和大家一起学习设计模式。在本次讲座中,我们将讨论工厂。我们将与您讨论使用此模板解决了哪些问题,并查看工厂如何帮助开设咖啡店的示例。我还将为您提供创建工厂的 5 个简单步骤。 为了与大家达成一致并轻松掌握本质,您应该熟悉以下主题:
- 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
可以分为两个部分:
- 在块中创建特定的咖啡实例
switch-case
。工厂所做的就是根据条件创建特定类型。 - 准备工作本身就是研磨、烹饪并倒入杯子中。
- 准备算法本身(研磨、烹饪和倒入杯子)将保持不变(至少我们希望如此)。
- 但咖啡的范围可能会改变。也许我们会开始制作摩卡..摩卡..摩卡奇...上帝保佑他,一种新型咖啡。
switch-case
。也有可能在我们的咖啡店里,这种方法orderCoffee
并不是我们制作不同类型咖啡的唯一地方。因此,必须在多个地方进行更改。你可能已经明白我的意思了。我们需要重构。将负责制作咖啡的块移到一个单独的类中有两个原因:
- 我们将能够在其他地方重用创建咖啡的逻辑。
- 如果范围发生变化,我们将不必在使用咖啡创建的所有地方编辑代码。仅在一处更改代码就足够了。
我们正在锯切我们的第一家工厂
为此,我们创建一个新类,该类仅负责创建咖啡类的必要实例: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
静态,一切都会变得更加简单。但这样我们就会失去两种可能性:
- 继承
SimpleCoffeeFactory
并覆盖createCoffee
. - 在我们的类中实现所需的工厂实现。
将工厂引入咖啡店
让我们使用工厂重写我们的咖啡厅类: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. 创建一个类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;
}
}
像一个老板一样。
GO TO FULL VERSION