澄清工厂方法设计模式的UML类图

Abd*_*man 3 uml design-patterns factory-pattern

我正在学习工厂方法设计模式,并在教程中发现了以下类图。我理解产品和具体产品部分,但 Creator 和 ConcreteCreator 部分对我来说有点模糊。如果有人澄清 UML 图,我将不胜感激。谢谢。 在此处输入图片说明

Bio*_*ode 8

工厂方法模式描述了一种封装和委托类型实例化的方法。工厂方法通常以Create...为前缀,例如Creator.CreateSpecializedObject()定义抽象。

这种模式的目的是将被消费对象实例的实例化和初始化从调用者或消费者(超类或基类)委托给更专门的子类。

由于工厂方法应该返回生产实例的抽象类型,消费者(例如超类/基类)可以提前创建和消费生产类型的实例,而无需知道具体实现。消费者只对抽象进行操作。

工厂方法允许为需要对抽象类型的实例进行操作的类型实现默认行为。然后,继承者提供此抽象类型的专用实现,继承者必须覆盖/实现抽象工厂方法以返回此类型。

向下滚动以查看此模式的简要示例...


在 UML 模型语言中,像字段这样的类成员称为Attribute,方法称为Operation。在 UML 中,一切都有一个含义,例如符号、线条的笔触样式、箭头设计和字体格式(如斜体字母)。

图表说: 在此处输入图片说明

a)我们有一个抽象类型Product
我们知道它是抽象的,因为类名是用斜体字母写的。

b)有一个具体的类ConcreteProduct
我们知道它是具体的,即实现,因为类名是用普通字母写的。

c)中的箭头,从点ConcreteProductProduct介绍ConcreteProduct继承ProductGeneralization)。
我们知道,因为空心箭头总是象征着继承,总是从子类(继承类型)指向超类(基类型,子类的泛化)。

该箭头表示:“{type_B} 是 {type_A} 的子类”
“{type_B} {type_A}”

当抽象类型是接口时,您会用虚线空心箭头(方向相同)替换箭头。

ClassA接口之间的关系称为实现
ClassA与其父(超类)之间的关系称为泛化

d)然后我们有另一个抽象类Creator,它将公共操作(方法)FactoryMethod()和另一个公共操作声明AnOperation()为契约,每个非抽象继承者都必须实现。
我们知道这两种方法都是公共的,因为前缀+象征着公共可见性(对于属性和操作)。

e)根据附加的箭头,我们可以看出ConcreteCreator继承自Creator,因此需要实现合约中Creator声明的公共或虚拟属性和操作。

f)此外,它对ConcreteCreatortype 有依赖性ConcreteProduct,因为它实例化并返回此类型。我们知道它是一个依赖项,因为依赖项由虚线实线箭头表示。这个箭头总是从依赖对象指向它依赖的对象。

它表示"{type_X} 需要/知道/使用 {type_Y}"
"{type_X} ? {type_Y}"

g)两个看起来像纸片的盒子用来注释图表的元素。在这种情况下,它会通知操作的返回值。

或者(最好)您可以使用冒号将返回值添加到签名定义中:。冒号介绍了返回值的类型,这是void在操作不返回任何内容的情况下。
以下签名描述了一个不带参数并返回类型实例的操作Product+FactoryMethod(void):Product

虚拟属性或方法的可见性由其以斜体字母书写的成员名称标识,而其他访问修饰符(可见性)由属性或操作名称之前的符号标识(+:public、-:private、#:protected、~:内部或包装)。


您不能创建抽象类型(抽象类和接口)的实例,只能创建具体类型。如果抽象类型的继承者本身不是抽象的,则它必须提供所有未声明为virtual或私有的成员的实现。

抽象类型是契约或保证,所有继承者(抽象或具体实现)都将具有在该契约中定义的成员。因此,您知道从Creatoreg继承的每个类型都ConcreteCreator必须FactoryMethod()实现一个方法。

在高级编程中,您只使用抽象类型作为成员类型声明。不是使用派生类型创建本地、实例或类成员或参数字段,例如ConcreteCreator,您使用提供所需功能的最不专业的超类或接口,例如Creator。您通常像这样使用它:

// Instead of: 
// ConcreteCreator concreteCreator = new ConcreteCreator();
Creator creator = new ConcreteCreator();

// Because 'Creator' defines a contract, 
// we know we can always invoke a method called 'FactoryMethod()' 
// on every type that inherits from 'Creator'
// and that the return value is guaranteed 
// to be an instance of type 'Product'
Product product = creator.FactoryMethod();
Run Code Online (Sandbox Code Playgroud)

实现的工厂方法ConcreteCreator.FactoryMethod()返回一个ConcreteProduct来满足抽象Creator类型定义的契约。这个契约定义了一个类型的返回值ProductConcreteProduct可分配给Product因为 'ConcreteProduct' 继承Product.

工厂方法示例

// Abstract creator.
// This abstract class provides a default behavior 
// to pickup and transport persons using a vehicle.
// The actual transportation vehicle is 
// created by the inheritor.
abstract class Driver
{
  // The abstract factory methodthat the inheritor has to implement.
  protected abstract Vehicle CreateVehicle();

  protected List<Persons> PickUpPersons(List<Destination> destinations)
  {    
    List<Person> result = new List<Person>();

    Vehicle vehicle = CreateVehicle();
    foreach (Destination destination in destinations)
    {
      Location location = vehicle.Move(destination);
      Person pickedUpPerson = location.GetPerson();
      result.Add(pickedUpPerson);
    }
    return result;
  }
}

// Concrete creator
class BusDriver extends Driver
{
  protected override Vehicle CreateVehicle()
  {
    // Bus implements Vehicle    
    Vehicle bus = new Bus();
    bus.Refuel(new Diesel(100));
    return bus;
  }

  public decimal StartJob()
  {
    List<Destination> destinations = GetBusStations();
    List<Person> persons = PickUpPersons(destinations);
    decimal pay = CollectMoney(persons);
    return pay;
  }
}

// Concrete creator
class TaxiDriver extends Driver
{
  protected override Vehicle CreateVehicle()
  {
    // Taxi implements Vehicle 
    Vehicle taxi = new Taxi();
    bus.Refuel(new Gasoline(50));
    Clean(taxi);
    return taxi;
  }

  public decimal StartJob()
  {
    List<Destination> destinations = AwaitCaller();
    List<Person> persons = PickUpPersons(destinations);
    decimal pay = CollectMoney(persons);
    return pay;
  }
}
Run Code Online (Sandbox Code Playgroud)

用法

class TransportationCompany
{
  public void RunBusiness()
  {
    BusDriver = busDriver = new BusDriver();
    decimal cash = busDriver.StartJob();

    TaxiDriver taxiDriver = new TaxiDriver();
    decimal moreCash = taxiDriver.StartJob();
  }
}
Run Code Online (Sandbox Code Playgroud)

评论

工厂方法模式还有另一个版本,它使用在类本身中定义的静态工厂方法来创建此类的实例:

class ConcreteProduct : Product
{
  public static Product Create()
  {
    Product newProduct = new ConcreteProduct();
    
    // Initialize or configure the new instance
    
    // Return the configured instance
    return newProduct
  }
}
Run Code Online (Sandbox Code Playgroud)

用法

class Program
{
  public static Main()
  {
    Product product = ConcreteProduct.Create();
  }
}
Run Code Online (Sandbox Code Playgroud)