在软件编程或开发中,设计模式是针对常见问题的可重用和经过文档记录的解决方案。在之前关于工厂模式的文章中,讨论了工厂模式的不同变体以及如何在它们之间做出选择。但似乎对于工厂方法模式和抽象工厂模式之间的区别存在一些混淆,因此本文将对它们进行详细探讨。
如果对理解工厂方法模式和抽象工厂模式之间的区别感到困惑,那么本文正是需要的。
首先,这两种模式都属于创建型模式的范畴,意味着它们旨在解决与对象创建相关的问题。工厂方法和抽象工厂都是关于创建对象的。
在本文中,还想强调另一个术语——简单工厂。
为了讨论,让设定一个简单的问题陈述。
类结构:
public interface ICustomer {
void AddPoints();
void AddDiscount();
}
public class GoldCustomer : ICustomer {
public void AddPoints() {
Console.WriteLine("Gold Customer - Points Added");
}
public void AddDiscount() {
Console.WriteLine("Gold Customer - Discount Added");
}
public void GoldOperation() {
Console.WriteLine("Operation specific to Gold Customer");
}
}
public class SilverCustomer : ICustomer {
public void AddPoints() {
Console.WriteLine("Silver Customer - Points Added");
}
public void AddDiscount() {
Console.WriteLine("Silver Customer - Discount Added");
}
public void SilverOperation() {
Console.WriteLine("Operation specific to Silver Customer");
}
}
问题陈述:
客户端希望创建客户对象(根据需求是黄金客户或白银客户)。
简单工厂:
这不是一个来自GOF(四人帮)的模式,但大多数人认为这是默认的工厂方法模式。在这里,将对象创建过程从客户端代码中取出,并放入另一个类中。
class CustomerFactory {
public static ICustomer GetCustomer(int i) {
switch(i) {
case 1:
GoldCustomer goldCustomer = new GoldCustomer();
goldCustomer.GoldOperation();
goldCustomer.AddPoints();
goldCustomer.AddDiscount();
return goldCustomer;
case 2:
SilverCustomer silverCustomer = new SilverCustomer();
silverCustomer.SilverOperation();
silverCustomer.AddPoints();
silverCustomer.AddDiscount();
return silverCustomer;
default:
return null;
}
}
}
客户端代码:
ICustomer c = CustomerFactory.GetCustomer(someIntegerValue);
工厂方法模式:
在这种模式中,定义一个接口,该接口将暴露一个方法来为创建对象。该方法的返回类型永远不会是具体类型,而是某个接口(或者可能是一个抽象类)。
public abstract class BaseCustomerFactory {
public ICustomer GetCustomer() {
ICustomer myCust = this.CreateCustomer();
myCust.AddPoints();
myCust.AddDiscount();
return myCust;
}
public abstract ICustomer CreateCustomer();
}
public class GoldCustomerFactory : BaseCustomerFactory {
public override ICustomer CreateCustomer() {
GoldCustomer objCust = new GoldCustomer();
objCust.GoldOperation();
return objCust;
}
}
public class SilverCustomerFactory : BaseCustomerFactory {
public override ICustomer CreateCustomer() {
SilverCustomer objCust = new SilverCustomer();
objCust.SilverOperation();
return objCust;
}
}
客户端代码:
BaseCustomerFactory c = new GoldCustomerFactory();
// 或者 new SilverCustomerFactory();
ICustomer objCust = c.GetCustomer();
注意:要了解何时使用简单工厂以及何时使用工厂方法模式,请。
在抽象工厂中,定义一个接口,该接口将创建相关或依赖的对象系列。换句话说,接口将暴露多个方法,每个方法都会创建某个对象。同样,这里的方法返回类型将是通用接口。所有这些对象将一起成为某些重要功能的一部分。
问题:如果每个工厂都将创建多个对象,并且所有这些对象都将相互关联(意味着它们将相互使用),那么这种关联是如何发生的,谁做的?
答案:将有一个中介类与接口有组合关系。这个类将使用从接口方法获得的所有对象完成所有工作。这将是客户端与之交互的类。
让讨论一个场景。想要构建一台桌面机器。让看看最好的设计是什么。
public interface IProcessor {
void PerformOperation();
}
public interface IHardDisk {
void StoreData();
}
public interface IMonitor {
void DisplayPicture();
}
public class ExpensiveProcessor : IProcessor {
public void PerformOperation() {
Console.WriteLine("Operation will perform quickly");
}
}
public class CheapProcessor : IProcessor {
public void PerformOperation() {
Console.WriteLine("Operation will perform Slowly");
}
}
public class ExpensiveHDD : IHardDisk {
public void StoreData() {
Console.WriteLine("Data will take less time to store");
}
}
public class CheapHDD : IHardDisk {
public void StoreData() {
Console.WriteLine("Data will take more time to store");
}
}
public class HighResolutionMonitor : IMonitor {
public void DisplayPicture() {
Console.WriteLine("Picture quality is Best");
}
}
public class LowResolutionMonitor : IMonitor {
public void DisplayPicture() {
Console.WriteLine("Picture quality is Average");
}
}
工厂代码如下:
public interface IMachineFactory {
IProcessor GetRam();
IHardDisk GetHardDisk();
IMonitor GetMonitor();
}
public class HighBudgetMachine : IMachineFactory {
public IProcessor GetRam() {
return new ExpensiveProcessor();
}
public IHardDisk GetHardDisk() {
return new ExpensiveHDD();
}
public IMonitor GetMonitor() {
return new HighResolutionMonitor();
}
}
public class LowBudgetMachine : IMachineFactory {
public IProcessor GetRam() {
return new CheapProcessor();
}
public IHardDisk GetHardDisk() {
return new CheapHDD();
}
public IMonitor GetMonitor() {
return new LowResolutionMonitor();
}
}
假设将来...LowBudgetMachine中的Ram决定升级,那么首先使LowBudgetMachine中的GetRam成为虚拟的,并创建一个新类:
public class AverageBudgetMachine : LowBudgetMachine {
public override IProcessor GetRam() {
return new ExpensiveProcessor();
}
}
计算机商店:
public class ComputerShop {
IMachineFactory category;
public ComputerShop(IMachineFactory _category) {
category = _category;
}
public void AssembleMachine() {
IProcessor processor = category.GetRam();
IHardDisk hdd = category.GetHardDisk();
IMonitor monitor = category.GetMonitor();
// 使用所有三个并创建机器
processor.PerformOperation();
hdd.StoreData();
monitor.DisplayPicture();
}
}
客户端代码:
IMachineFactory factory = new HighBudgetMachine();
// 或者 new LowBudgetMachine();
ComputerShop shop = new ComputerShop(factory);
shop.AssembleMachine();
现在应该了解了工厂方法模式和抽象工厂模式之间的区别。希望喜欢阅读这篇文章。感谢耐心。