65.9K
CodeProject 正在变化。 阅读更多。
Home

工厂方法模式 vs. 抽象工厂模式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (82投票s)

2014年1月27日

CPOL

3分钟阅读

viewsIcon

323249

downloadIcon

4632

在本文中,我们将学习工厂方法模式和抽象工厂模式之间的区别。

引言

设计模式是针对软件编程或开发中常见问题的可重用和有文档记录的解决方案。

在我之前的一篇关于工厂模式的文章中,我谈到了工厂模式的不同种类以及如何在它们之间进行选择。 但我认为在工厂方法模式和抽象工厂方面存在一些混淆。 所以我们来研究一下。

谁应该阅读本文?

如果您对理解工厂方法模式和抽象工厂模式之间的区别感到困惑,那么您来对地方了。

 

这两个是什么? 

 

  • 首先,它们都属于创建型类别,这意味着它将解决与对象创建相关的问题。
  • 工厂方法和抽象工厂模式都与创建对象有关。

 

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

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");
    }
}

问题陈述

客户希望创建 Customer 对象(基于需求,可以是 Gold 或 Silver)。

简单工厂

这是并非源自 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;
        }      
    }
}

//Client Code
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;
    }
}
//Client Code
BaseCustomerFactory c = new GoldCustomerFactory();// Or 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(); }
}
//Let's say in future...Ram in the LowBudgetMachine is decided to upgrade then
//first make GetRam in LowBudgetMachine Virtual and create new class as follows

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();
        //use all three and create machine

        processor.PerformOperation();
        hdd.StoreData();
        monitor.DisplayPicture();
    }
}
//Client Code
IMachineFactory factory = new HighBudgetMachine();// Or new LowBudgetMachine();
ComputerShop shop = new ComputerShop(factory);
shop.AssembleMachine();   

结论

我想现在您知道了工厂方法模式和抽象工厂模式之间的区别

希望大家喜欢阅读这篇文章。感谢您的耐心。

有关包括 ASP.NET、设计模式、WCF 和 MVC 在内的各种主题的技术培训,请联系SukeshMarla@Gmail.com或访问www.sukesh-marla.com

想要更多类似内容,请单击此处。 订阅文章更新 或在推特上关注@SukeshMarla 

© . All rights reserved.