2009-10-05 66 views

回答

12

虽然这并不一定是它的主要用途,这是很好的东西,你有专门的一个类的实例:

public ITax BuildNewSalesTax() 
public ITax BuildNewValueAddedTax() 

您需要两种方法来建立一个征税对象,但你不想每次都必须依赖于使用“新”,因为构造函数可能很复杂。通过这种方式,我可以将所有更改封装到单个方法中,以供其他人在未来进行维护时使用。

31

我有两种情况下,我倾向于使用它:

  1. 需要以某种特定方式要被初始化的对象
  2. 当我想构造基于抽象类型的特定类型(一个抽象类或接口)。

例子:

  1. 第一种情况可能是你想拥有一个工厂创建SqlCommand对象,在那里你会自动返回命令对象之前附上有效SqlConnection

  2. 第二种情况是如果您有一个接口定义并确定在执行时使用哪个接口的确切实现(例如通过在配置文件中指定它)。

0

向你从我的观点问题答案的第二部分,我认为这是比“新”关键字更好的原因是工厂方法减少了对特定类的构造函数的扶养。通过使用工厂方法,可以将有问题的对象的创建委派给其他人,因此调用者不需要了解如何创建对象。

20

您可以参考框架设计指南第2版第9.5节“工厂”。下面是引用对于一套指引,使用工厂在构造函数:

DO喜欢构造函数来 工厂,因为他们通常 更多可用的,一致的, 比专业 建设机制方便。

考虑使用一个工厂,如果你需要更多的 比的控制可以通过 构造了创建 实例来提供。

DO使用的情况下,其中一个 显影剂可能不知道来构造该类型 ,工厂这样的编码 针对基类型或接口时。

考虑使用工厂如果有 命名方法是使 操作不言自明的唯一方法。

DO使用工厂转换式 操作。

并从第5节开始。3构造设计

考虑使用构造的静态工厂方法代替,如果所需要的操作的 语义,或者如果下面的构造设计指导 不直接映射到建筑 重刑一个新的实例感觉不自然。

0

最好有一个工厂方法模式与新的关键字。这个想法是移动业务逻辑之外的对象的完整实例化。这个原则是dependency injection的症结所在。而且,工厂方法的工作可以在稍后的时间委托给Spring.net或Castle Windsor之类的依赖注入框架。

+1

我在每一个“新”与工厂的代表,充分的IoC Containered更换一个代码库工作。与之合作是一场噩梦。经过一年半的开发与5个开发人员,它被废弃。 3个开发者使用行业标准做法在1个月内取代了功能。根据我的经验,工厂在@Dzmitri指出的情况下非常有用。除非你打算通过配置来切换类型,或者有非常有趣的构造函数逻辑,否则我认为用工厂替换新的方法是过分的,并且适得其反。 – Fred 2016-04-05 15:27:57

1

当系统应该独立于其产品的创建,组成和表示方式时,使用抽象工厂模式。 系统应该配置多个产品系列之一。 相关产品对象系列旨在一起使用,并且您需要强制执行此约束。 你想提供一个产品类库,并且你只想揭示它们的接口,而不是它们的实现。

-1

我想它是什么时候你希望你的应用程序在未经编码改变的情况下在未来是松散耦合和可扩展的。

我在博客上写了一篇文章,为什么我在我的项目中选择工厂模式,可能会给你更多的见解。这个例子是在PHP中,但我认为它通常适用于所有语言。

http://www.mixedwaves.com/2009/02/implementing-factory-design-pattern/

5

我使用出厂时图纹

  1. 当一个类不知道它必须创造哪些对象的类。

  2. 一个类指定了它的子类来指定要创建的对象。

  3. 在程序员的语言(非常原始的形式)中,您可以使用工厂模式,您必须根据提供的数据创建任何一个子类的对象。

24

,当你想用不同的组件重用常用功能使用工厂方法(不是抽象工厂)。

例:想象一下,你有一个M16步枪。像这样的:

public class M16 
{ 
    private Scope scope = new StandardScope(); 
    private SecondaryWeapon secondary = new Bayonet(); 
    private Camouflage camo = new DesertCamo(); 

    public double getMass() 
    { 
     // Add the mass of the gun to the mass of all the attachments. 
    } 

    public Point2D shootAtTarget(Point2D targetPosition) 
    { 
     // Very complicated calculation taking account of lots of variables such as 
     // scope accuracy and gun weight. 
    } 
} 

你可能会满意它一段时间,认为你不会想改变任何东西。但是那时你必须在丛林中进行秘密的夜间隐形任务,并且你意识到你的依恋完全不合适。你真的需要一个NightVision示波器,JungleCamo和一个GrenadeLauncher辅助武器。你将不得不从原来的M16复制过来的代码......不够好的可扩展性.....工厂方法来拯救!

重写你的M16类:

public abstract class M16 
{ 
    private Scope scope = getScope(); 
    private SecondaryWeapon secondary = getSecondaryWeapon(); 
    private Camouflage camo = getCamouflage(); 

    public double getMass() 
    { 
     // Add the mass of the gun to the mass of all the attachments. 
    } 

    public Point2D shootAtTarget(Point2D targetPosition) 
    { 
     // Very complicated calculation taking account of lots of variables such as 
     // scope accuracy and gun weight. 
    } 

    // Don't have to be abstract if you want to have defaults. 
    protected abstract Scope getScope(); 
    protected abstract SecondaryWeapon getSecondaryWeapon(); 
    protected abstract Camouflage getCamouflage(); 
} 


//Then, your new JungleM16 can be created with hardly any effort (and importantly, no code //copying): 

public class JungleM16 : M16 
{ 
    public Scope getScope() 
    { 
     return new NightVisionScope(); 
    } 

    public SecondaryWeapon getSecondaryWeapon() 
    { 
     return new GrenadeLauncher(); 
    } 

    public Camouflage getCamouflage() 
    { 
     return new JungleCamo(); 
    } 
} 

主要的想法?在保留常用功能的同时自定义和交换合成对象。

实际有用的地方使用它: 你刚刚设计了一个很酷的图形用户界面,而且它有一个非常复杂的布局。如果你想拥有不同的小部件,那么再次布置所有东西将是一件非常痛苦的事情。所以......使用工厂方法来创建小部件。然后,如果您改变了主意(或者其他人想要使用您的类,但使用不同的组件),那么您可以继承GUI的子类并覆盖工厂方法。

+2

嘿它的一个很好的解释,你写了任何教程,我爱爱读它们..! – 2012-03-25 19:22:31

+1

嘿,好的解释。它使理解起来更容易。做得好。 – Flavio 2017-07-02 11:29:28

0

工厂模式与对象的实例化比不暴露实例化逻辑。换句话说,Factory实际上是具有通用接口的对象的创建者。

它让子类来决定实例化哪一个类。

请看下面的例子:

namespace TestApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Store is ordering the factory to get office shoes 
      Shoe shoe = ShoeFactory.GetShoes("OFFICE"); 
      Console.WriteLine(shoe.GetType()); //Will be office shoes 

      //Store is ordering the factory to get sports shoes 
      shoe = ShoeFactory.GetShoes("SPORTS"); 
      Console.WriteLine(shoe.GetType()); //Will be sports shoes 
     } 
    } 

    //This is the factory supplying shoes. It can supply sports shoes or office shoes 
    //based on demand 
    class ShoeFactory 
    { 
     public static Shoe GetShoes(string strShoeType) 
     { 
      switch (strShoeType) 
      { 
       case "SPORTS": return new SportShoe(); 
        break; 
       case "OFFICE": return new OfficeShoe(); 
        break; 
       default: 
        return null; 
      } 
     } 
    } 

    //This is an abstract class representing product family 
    //In this example, its shoe 
    public abstract class Shoe 
    { 

    } 

    //Office shoe is a concrete class belongs to shoe family 
    class OfficeShoe : Shoe 
    { 

    } 

    //Sports shoe is a concrete class belongs to shoe family 
    class SportShoe : Shoe 
    { 

    } 
} 
+0

但是,我们也在这里使用新的关键字。 开关(strShoeType) { 案 “SPORTS”:返回新运动鞋展(); 突破; case“OFFICE”:return new OfficeShoe(); 突破; 默认值: 返回null; } 那为什么我们把它作为一个工厂模式 – 2017-12-12 11:50:55