0

可能重复:
.NET Framework 中的构造函数与工厂

我了解工厂模式并已实施,但无法获得它将带来什么好处。例如,而不是:

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

写作:

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

是我错过了还是没有怀孕。能否请您举出您自己的经验示例。

4

4 回答 4

3

工厂模式的一些好处:

  1. 您可以跟踪您创建的对象。如果您想重用对象或强制限制创建的对象数量,工厂可以强制执行。
  2. 您可以控制对象的创建方式。如果有一些参数用于创建对象,您可以在客户端为已创建的对象传递相同参数时返回现有对象。
  3. 您可以让工厂返回一个接口,但在内部创建支持该接口的不同类型的对象。
于 2012-08-09T00:47:39.023 回答
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 中应用工厂模式可以非常强大且独特。

于 2012-08-09T01:36:26.863 回答
1

工厂模式的好处在于它封装了构造的细节和具体的使用方式。这使您可以在以后以更少的地方进行更改,从而演变为更有趣的设计。

考虑这个例子:

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

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

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

当然,投机工厂对此似乎有些笨拙,这就是我更喜欢封装构造函数的原因。

于 2012-08-09T01:01:41.820 回答
1

工厂模式之所以好的原因有很多

其中几个是:

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

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

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

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

例如

此类依赖于 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");
    }
}
于 2012-08-09T00:40:05.910 回答