何时使用Factory方法模式?
请告诉我何时在项目中使用它? 以及它如何比新关键字更好?
答案 0 :(得分:35)
我有两种情况我倾向于使用它:
<强>示例:强>
第一种情况可能是您希望工厂创建SqlCommand
对象,在返回命令对象之前自动附加有效SqlConnection
。< / p>
第二种情况是指您定义了一个接口,并在执行时确定要使用的接口的确切实现(例如,通过在配置文件中指定它)。
答案 1 :(得分:34)
如果要重用不同组件的常用功能,请使用工厂方法(非抽象工厂)。
示例:想象一下你有一把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,它的布局非常复杂。如果你想拥有不同的小部件,那么必须再次布局一切将是一件非常痛苦的事。所以.....使用工厂方法来创建小部件。然后,如果你改变主意(或者其他人想要使用你的类,但使用不同的组件),你可以只是继承GUI并覆盖工厂方法。
答案 2 :(得分:24)
您可以参阅第9.5节“框架设计指南第2版”中的“工厂”。以下是关于使用工厂而不是构造函数的引用指南:
更喜欢施工人员 工厂,因为他们是 通常更有用,更一致, 比专业方便 建设机制。
如果需要,请考虑使用工厂 比可以提供更多的控制 建设者在创造 实例
在a的情况下,请使用工厂 开发人员可能不知道哪种类型 构造,例如编码时 对基本类型或接口。
如果有工厂,请考虑使用工厂 命名方法是唯一的方法 操作不言自明。
请使用工厂进行转换 操作
从第5.3节“构造函数设计”
开始CONSIDER使用静态工厂方法而不是构造函数 所需操作的语义不直接映射到构造 - 一个新实例,或者如果遵循构造函数设计指南 感觉不自然。
答案 3 :(得分:16)
虽然这不一定是它的主要用途,但对于你有专门的类实例的东西是好的:
public ITax BuildNewSalesTax()
public ITax BuildNewValueAddedTax()
您需要两种方法来构建税对象,但您不希望每次都依赖于使用“new”,因为构造函数可能很复杂。通过这种方式,我将所有更改封装到一个方法中,这个方法对于其他人来说是清楚的,以便将来进行维护。
答案 4 :(得分:6)
我在
时使用工厂图案当一个类不知道它必须创建哪个类对象时。
类指定其子类以指定要创建的对象。
在程序员的语言(非常原始的形式)中,您可以使用工厂模式,您必须根据提供的数据创建任何一个子类的对象。
答案 5 :(得分:3)
当需要生成属于特定族的对象时,可以使用工厂方法模式。除此要求外,您还希望在一个地方保留有关对象实例化的决策。
有关详细信息,请参阅以下链接。
http://xeon2k.wordpress.com/2010/11/27/factory-method-pattern/
答案 6 :(得分:2)
何时使用抽象工厂模式 系统应独立于其产品的创建,组合和表示方式。 系统应配置多个产品系列之一。 一系列相关产品对象旨在一起使用,您需要强制执行此约束。 你想提供一个产品类库,你想要只揭示它们的接口,而不是它们的实现。
答案 7 :(得分:2)
工厂模式处理对象的实例化而不暴露实例化逻辑。换句话说,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
{
}
}
答案 8 :(得分:1)
最好有一个工厂方法模式与新关键字。我们的想法是在业务逻辑之外移动对象的完整实例化。这个原则是dependency injection的关键。并且,工厂方法的工作可以稍后委托给Spring.net或Castle Windsor等依赖注入框架。
答案 9 :(得分:-1)
从我的观点回答你问题的第二部分,我认为它比'new'关键字更好的原因是工厂方法降低了对特定类的构造函数的依赖性。通过使用工厂方法,您可以将相关对象的创建委托给其他人,因此调用者不需要知道如何创建对象。
答案 10 :(得分:-2)
我认为,当您希望应用程序在未来编码更改时可以松散耦合和扩展时。
我在博客上发了一篇文章,说明为什么我在项目中选择工厂模式,可能会给你更多的见解。这个例子是在PHP中,但我认为它适用于所有语言。
http://www.mixedwaves.com/2009/02/implementing-factory-design-pattern/