设计模式解析:工厂方法与抽象工厂

在软件编程或开发中,设计模式是针对常见问题的可重用和经过文档记录的解决方案。在之前关于工厂模式的文章中,讨论了工厂模式的不同变体以及如何在它们之间做出选择。但似乎对于工厂方法模式和抽象工厂模式之间的区别存在一些混淆,因此本文将对它们进行详细探讨。

如果对理解工厂方法模式和抽象工厂模式之间的区别感到困惑,那么本文正是需要的。

首先,这两种模式都属于创建型模式的范畴,意味着它们旨在解决与对象创建相关的问题。工厂方法和抽象工厂都是关于创建对象的。

在本文中,还想强调另一个术语——简单工厂。

1. 简单工厂与工厂方法

为了讨论,让设定一个简单的问题陈述。

类结构:

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();

注意:要了解何时使用简单工厂以及何时使用工厂方法模式,请。

2. 抽象工厂模式

在抽象工厂中,定义一个接口,该接口将创建相关或依赖的对象系列。换句话说,接口将暴露多个方法,每个方法都会创建某个对象。同样,这里的方法返回类型将是通用接口。所有这些对象将一起成为某些重要功能的一部分。

问题:如果每个工厂都将创建多个对象,并且所有这些对象都将相互关联(意味着它们将相互使用),那么这种关联是如何发生的,谁做的?

答案:将有一个中介类与接口有组合关系。这个类将使用从接口方法获得的所有对象完成所有工作。这将是客户端与之交互的类。

让讨论一个场景。想要构建一台桌面机器。让看看最好的设计是什么。

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();

现在应该了解了工厂方法模式和抽象工厂模式之间的区别。希望喜欢阅读这篇文章。感谢耐心。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485