如何使用工厂模式?

时间:2012-08-09 00:32:39

标签: c# .net factory-pattern

  

可能重复:
  Constructor vs. Factory in .NET Framework

我理解工厂模式已实施但无法获得它带来的好处。例如,而不是:

MyType1 obj=new Mytype1();
MyType2 obj=new Mytype2();

写作:

IMyType obj1 = Factory.Create(1);
IMyType obj2 = Factory.Create(2);

这是我错过了还是没有想到的东西。你能不能把自己的经验付诸实践。

4 个答案:

答案 0 :(得分:3)

工厂模式的一些好处:

  1. 您可以跟踪您创建的对象。如果要重新使用对象或对创建的对象数量实施限制,工厂可以强制执行该操作。
  2. 您可以控制对象的创建方式。如果有一些参数用于创建对象,则当客户端为已创建的对象传入相同的参数时,可以返回现有对象。
  3. 您可以让工厂返回一个接口,但在内部创建支持该接口的不同类型的对象。

答案 1 :(得分:1)

出于多种原因,工厂模式很好

其中几个是:

  • 您可以初始化工厂中的项目(默认值等)并使项目创建程序化(查看其他类/过程,获取默认值,检查配置值)。

构造函数是创建项的一种方法,但是如果不将类紧密耦合到这些依赖项,则无法检查其他类或运行新创建的实例之外的其他进程

  • 它为项目创建提供了一个中央存储库,可以在团队中的开发人员之间实施模式/实践

这些是我能想到的一些原因:)

e.g。

此类依赖于ConfigManager进行实例化

class SomeClass 
{
    public int SomeValue;

    public SomeClass() 
    {
        // Check the config for some value
        SomeValue = ConfigManager.GetDefaultInt("SomeValue");
    }
}

这个课不是因为它使用工厂

class SomeClass 
{
    public int SomeValue;

    public SomeClass() 
    {
    }
}

class SomeClassFactory 
{
    public SomeClass CreateSomeClass() 
    {
        SomeClass obj = new SomeClass();
        obj.SomeValue = ConfigManager.GetDefaultInt("SomeValue");
    }
}

答案 2 :(得分:1)

Factory模式的好处在于它根据使用方式封装了构造细节和特定类型。这使您可以在以后用更少的地方进行更改,从而演变为更有趣的设计。

考虑这个例子:

public interface IStorage
{
    void Save(SomeObject toSave);
    SomeObject Get(SomeId id);
}

public class DatabaseStorage : IStorage
{
    public void Save(SomeObject toSave)
    {
       //persist to DB somehow
    }

    public SomeObject Get(SomeId id)
    {
       //get from db somehow and return
    }
}

public class StorageFactory
{
    public IStorage GetStorage()
    {
         return new DatabaseStorage();
    }
}

public class DatabaseStorage : IStorage
{
    public void Save(SomeObject toSave)
    {
       //persist to DB somehow
    }

    public SomeObject Get(SomeId id)
    {
       //get from db somehow and return
    }
}

现在假设您以后需要缓存一些结果,或者记录所有结果。您可以创建一个代理,如下所示:

public class LoggingStorage : IStorage
{
    private readonly IStorage _proxied;

    public LoggingStorage(IStorage proxied)
    {
        _proxied = proxied;
    }

    public void Save(SomeObject toSave)
    {
       //log this call
       _proxied.Save(toSave);
    }

    public SomeObject Get(SomeId id)
    {
       //log this call
       return _proxied.Get(id);
    }
}

现在,如果您使用了构造函数,则必须替换它的每次使用以将其包装。如果您使用了工厂,则只需更改它:

public class StorageFactory
{
    public IStorage GetStorage()
    {
         return new LoggingStorage(new DatabaseStorage());
    }
}

当然,投机工厂看起来有点沉重,这就是为什么我更喜欢encapsulate the constructor

答案 3 :(得分:1)

jQuery是一个工厂函数,它利用JavaScript的工作方式来创建内存占用非常少的对象。

让我们通过一个可怕的残缺,大幅简化的jQuery版本进行调查,以帮助我们了解潜在的好处:

var $ = jQuery = (function(){ //this anon function fires once, and returns a function

//defines all kinds of internal functions jquery uses here

function jQuery(selector,context){ // we're going to return this inner JQ later
    //defines only the logic needed to decide what to do with the arguments here
    //and then builds the jQuery object with 'return new jQuery.prototype.init();'
}

//defines jQuery.prototype properties here:
jQuery.prototype = {
    //...
    init:function(selector,context){ //gets used to build the JQ objects
        this.constructor.prototype = jQuery.prototype; //hands off the function prototype
    }
    //...
}

return jQuery; //this gets assigned to the outer jQuery and $ vars

})()

所以...现在我们有一个工厂函数,它也像命名空间,我们可以扩展它的原型,并期望这些方法在它吐出的对象上可用。此外,除了它们通常包装的DOM对象之外,对象本身在内存中的权重非常小,因为所有函数都是从闭包中引入的引用或作为引用传递的外部原型对象。除了一些逻辑和一些状态变量之外,在向工厂函数的原型属性添加新方法时,当jQuery首次被解析或传递给原型对象时,构建对象所需的一切。

现在,尝试使用new jQuery()

执行此操作

如果有的话,在JavaScript中应用工厂模式可以是非常强大的。