阐明工厂方法设计模式的 UML class 图
Clarifying UML class diagram of Factory Method design pattern
我正在学习工厂方法设计模式,并在教程中找到以下 class 图。我了解 product 和 concreteProduct 部分,但 Creator 和 ConcreteCreator 部分对我来说看起来有点模糊。如果有人澄清了 UML 图,我将不胜感激。谢谢。
工厂方法模式描述了一种封装和委托类型实例化的方法。工厂方法通常以 Create... 作为前缀,例如Creator.CreateSpecializedObject()
并定义摘要。
此模式的目的是将调用者或消费者(superclass 或 base class)消费对象实例的实例化和初始化委托给更专门的 subclass.
由于工厂方法应该return生产实例的抽象类型,消费者例如superclass/base class 可以在不知道具体实现的情况下提前创建和使用生成类型的实例。消费者仅对抽象进行操作。
工厂方法允许为需要对抽象类型的实例进行操作的类型实现默认行为。然后由继承者提供此抽象类型的专门实现,继承者必须 override/implement 抽象工厂方法 return 此类型。
向下滚动查看此模式的简要示例...
在 UML 模型语言中,class 字段等成员称为 Attribute,方法称为 Operation。在 UML 中,一切都有意义,例如符号、线条的笔划样式、箭头设计和字体格式(如斜体字母)。
图表说:
a) 我们有一个抽象类型 Product
.
我们知道它是抽象的,因为class名字是用斜体字母写的。
b)有一个具体的class ConcreteProduct
.
我们知道它是具体的,即一个实现,因为 class 名字是用普通字母写的。
c)从ConcreteProduct
指向Product
的箭头说明ConcreteProduct
继承了Product
(Generalization
).
我们知道,因为空心箭头总是象征着继承,总是从subclass(继承类型)指向superclass(基类型,subclass的泛化)。
这个箭头表示:"{type_B}是{type_A}的子class"
或 "{type_B} {type_A}".
当抽象类型是一个接口时,您可以将箭头替换为空心虚线箭头(方向相同)。
一个classClassA
和接口之间的关系叫做实现。
classClassA
与其父class(superclass)之间的关系称为泛化.
d) 然后我们有另一个抽象 class Creator
,它声明了 public 操作(方法) FactoryMethod()
和另一个 public 操作 AnOperation()
作为契约,每个非抽象继承者 必须 实施。
我们知道这两种方法都是 public 因为前缀 +
,它象征着 public 可见性(对于属性和操作)。
e) 根据附件中的箭头我们可以看出ConcreteCreator
继承自Creator
因此需要在合约Creator
声明public或虚拟属性和操作。
f) 此外 ConcreteCreator
对类型 ConcreteProduct
有依赖性,因为它实例化并 returns 这种类型。我们知道它是一个依赖关系,因为依赖关系由虚线实心箭头表示。此箭头始终从依赖对象指向它所依赖的对象。
表示"{type_X} needs/knows/uses {type_Y}"
或 "{type_X} ⤑ {type_Y}".
g) 两个看起来像纸页的方框是用来注释图表的元素的。在这种情况下,它会通知操作的 return 值。
或者(最好)您可以使用冒号 :
将 return 值添加到签名定义中。冒号引入了 return 值的类型,如果操作 return 什么都没有,它将是 void
。
以下签名描述了一个不带参数的操作,并且 return 是类型 Product
的一个实例:+FactoryMethod(void):Product
虚拟属性或方法的可见性由它们的成员名称以斜体字母书写来标识,而其他访问修饰符(可见性)由属性或操作名称之前的符号标识(+
: public, -
: private, #
: protected, ~
: internal or package).
您不能创建抽象类型(抽象 classes 和接口)的实例,只能创建具体类型的实例。如果抽象类型的继承者本身不是抽象的,它 必须 提供所有未声明为 virtual
或私有的成员的实现。
抽象类型是一种契约或保证,所有继承者(抽象或具体实现)都将具有在该契约中定义的成员。因此,您知道每个继承自 Creator
的类型,例如 ConcreteCreator
必须实现一个方法 FactoryMethod()
。
在高级编程中,您只使用抽象类型作为成员类型声明。而不是使用派生类型创建本地、实例或 class 成员或参数字段,例如ConcreteCreator
,您使用最不专业的 superclass 或提供所需功能的接口,例如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();
实现的工厂方法ConcreteCreator.FactoryMethod()
return是ConcreteProduct
满足抽象Creator
类型定义的契约。此合同定义了 Product
类型的 return 值。
ConcreteProduct
可分配给 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;
}
}
用法
class TransportationCompany
{
public void RunBusiness()
{
BusDriver = busDriver = new BusDriver();
decimal cash = busDriver.StartJob();
TaxiDriver taxiDriver = new TaxiDriver();
decimal moreCash = taxiDriver.StartJob();
}
}
备注
还有另一个版本的工厂方法模式,它使用 class 本身定义的静态工厂方法来创建此 class:
的实例
class ConcreteProduct : Product
{
public static Product Create()
{
Product newProduct = new ConcreteProduct();
// Initialize or configure the new instance
// Return the configured instance
return newProduct
}
}
用法
class Program
{
public static Main()
{
Product product = ConcreteProduct.Create();
}
}
没有 Factory
设计模式(在 GoF 的书中)。您包含的图表接近 Factory Method
。 Method
是名字的必要组成部分,不能省略。
您提供的图表看起来像是 GoF 书中 class 图表的复制品。不幸的是,您的重现遗漏了一些关键点。下面是 GoF 书中的图表。
Factory Method
模式是 Template Method
的特例(或至少如上图 class 所示^)。
我经常觉得把它放在顺序图中更容易理解:
^ Factory Method
不必与 Template Method
一起使用。 Abstract Factory
是另一个使用 Factory Method
.
的示例
我正在学习工厂方法设计模式,并在教程中找到以下 class 图。我了解 product 和 concreteProduct 部分,但 Creator 和 ConcreteCreator 部分对我来说看起来有点模糊。如果有人澄清了 UML 图,我将不胜感激。谢谢。
工厂方法模式描述了一种封装和委托类型实例化的方法。工厂方法通常以 Create... 作为前缀,例如Creator.CreateSpecializedObject()
并定义摘要。
此模式的目的是将调用者或消费者(superclass 或 base class)消费对象实例的实例化和初始化委托给更专门的 subclass.
由于工厂方法应该return生产实例的抽象类型,消费者例如superclass/base class 可以在不知道具体实现的情况下提前创建和使用生成类型的实例。消费者仅对抽象进行操作。
工厂方法允许为需要对抽象类型的实例进行操作的类型实现默认行为。然后由继承者提供此抽象类型的专门实现,继承者必须 override/implement 抽象工厂方法 return 此类型。
向下滚动查看此模式的简要示例...
在 UML 模型语言中,class 字段等成员称为 Attribute,方法称为 Operation。在 UML 中,一切都有意义,例如符号、线条的笔划样式、箭头设计和字体格式(如斜体字母)。
图表说:
a) 我们有一个抽象类型 Product
.
我们知道它是抽象的,因为class名字是用斜体字母写的。
b)有一个具体的class ConcreteProduct
.
我们知道它是具体的,即一个实现,因为 class 名字是用普通字母写的。
c)从ConcreteProduct
指向Product
的箭头说明ConcreteProduct
继承了Product
(Generalization
).
我们知道,因为空心箭头总是象征着继承,总是从subclass(继承类型)指向superclass(基类型,subclass的泛化)。
这个箭头表示:"{type_B}是{type_A}的子class"
或 "{type_B} {type_A}".
当抽象类型是一个接口时,您可以将箭头替换为空心虚线箭头(方向相同)。
一个classClassA
和接口之间的关系叫做实现。
classClassA
与其父class(superclass)之间的关系称为泛化.
d) 然后我们有另一个抽象 class Creator
,它声明了 public 操作(方法) FactoryMethod()
和另一个 public 操作 AnOperation()
作为契约,每个非抽象继承者 必须 实施。
我们知道这两种方法都是 public 因为前缀 +
,它象征着 public 可见性(对于属性和操作)。
e) 根据附件中的箭头我们可以看出ConcreteCreator
继承自Creator
因此需要在合约Creator
声明public或虚拟属性和操作。
f) 此外 ConcreteCreator
对类型 ConcreteProduct
有依赖性,因为它实例化并 returns 这种类型。我们知道它是一个依赖关系,因为依赖关系由虚线实心箭头表示。此箭头始终从依赖对象指向它所依赖的对象。
表示"{type_X} needs/knows/uses {type_Y}"
或 "{type_X} ⤑ {type_Y}".
g) 两个看起来像纸页的方框是用来注释图表的元素的。在这种情况下,它会通知操作的 return 值。
或者(最好)您可以使用冒号 :
将 return 值添加到签名定义中。冒号引入了 return 值的类型,如果操作 return 什么都没有,它将是 void
。
以下签名描述了一个不带参数的操作,并且 return 是类型 Product
的一个实例:+FactoryMethod(void):Product
虚拟属性或方法的可见性由它们的成员名称以斜体字母书写来标识,而其他访问修饰符(可见性)由属性或操作名称之前的符号标识(+
: public, -
: private, #
: protected, ~
: internal or package).
您不能创建抽象类型(抽象 classes 和接口)的实例,只能创建具体类型的实例。如果抽象类型的继承者本身不是抽象的,它 必须 提供所有未声明为 virtual
或私有的成员的实现。
抽象类型是一种契约或保证,所有继承者(抽象或具体实现)都将具有在该契约中定义的成员。因此,您知道每个继承自 Creator
的类型,例如 ConcreteCreator
必须实现一个方法 FactoryMethod()
。
在高级编程中,您只使用抽象类型作为成员类型声明。而不是使用派生类型创建本地、实例或 class 成员或参数字段,例如ConcreteCreator
,您使用最不专业的 superclass 或提供所需功能的接口,例如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();
实现的工厂方法ConcreteCreator.FactoryMethod()
return是ConcreteProduct
满足抽象Creator
类型定义的契约。此合同定义了 Product
类型的 return 值。
ConcreteProduct
可分配给 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;
}
}
用法
class TransportationCompany
{
public void RunBusiness()
{
BusDriver = busDriver = new BusDriver();
decimal cash = busDriver.StartJob();
TaxiDriver taxiDriver = new TaxiDriver();
decimal moreCash = taxiDriver.StartJob();
}
}
备注
还有另一个版本的工厂方法模式,它使用 class 本身定义的静态工厂方法来创建此 class:
的实例class ConcreteProduct : Product
{
public static Product Create()
{
Product newProduct = new ConcreteProduct();
// Initialize or configure the new instance
// Return the configured instance
return newProduct
}
}
用法
class Program
{
public static Main()
{
Product product = ConcreteProduct.Create();
}
}
没有 Factory
设计模式(在 GoF 的书中)。您包含的图表接近 Factory Method
。 Method
是名字的必要组成部分,不能省略。
您提供的图表看起来像是 GoF 书中 class 图表的复制品。不幸的是,您的重现遗漏了一些关键点。下面是 GoF 书中的图表。
Factory Method
模式是 Template Method
的特例(或至少如上图 class 所示^)。
我经常觉得把它放在顺序图中更容易理解:
^ Factory Method
不必与 Template Method
一起使用。 Abstract Factory
是另一个使用 Factory Method
.