何时使用Factory方法模式?

Jas*_*wal 34 c# design-patterns factory

何时使用Factory方法模式?

请提供一些具体的想法何时在项目中使用它?以及它如何比新关键字更好的方式?

Fre*_*örk 35

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

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

例子:

  1. 第一种情况可能是您希望工厂创建SqlCommand对象,SqlConnection在返回命令对象之前自动附加有效对象.

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


Kev*_*vin 35

如果要重用不同组件的常用功能,请使用工厂方法(非抽象工厂).

示例:想象一下你有一把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.
    }
}
Run Code Online (Sandbox Code Playgroud)

你可能会对它感到满意,认为你不想改变任何东西.但是你必须在丛林中做一个秘密的夜间秘密任务,你会发现你的附件是完全不合适的.你真的需要一个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();
    }
}
Run Code Online (Sandbox Code Playgroud)

大意?在保持常用功能的同时自定义和交换合成对象.

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

  • 嘿,这是一个很好的解释,你有没有写过我喜欢的任何教程来阅读它们. (3认同)

Dzm*_*uba 24

您可以参考框架设计指南第2版中的9.5工厂.以下是关于使用工厂而不是构造函数的引用指南集:

更喜欢施工人员到工厂,因为它们通常比专业的施工机制更有用,更一致,更方便.

如果您需要比构造函数在创建实例时提供的更多控制,请考虑使用工厂.

如果开发人员可能不知道要构造哪种类型,例如在对基本类型或接口进行编码时,请使用工厂.

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

请使用工厂进行转换式操作.

并从第5.3节构造函数设计

如果所需操作的语义不直接映射到新实例的构造,或者遵循构造函数设计指南感觉不自然,则考虑使用静态工厂方法而不是构造函数.


Aus*_*tin 16

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

public ITax BuildNewSalesTax()
public ITax BuildNewValueAddedTax()
Run Code Online (Sandbox Code Playgroud)

您需要两种方法来构建税对象,但您不希望每次都依赖于使用"new",因为构造函数可能很复杂.这样,我将所有更改封装到一个方法中,这个方法对于其他人来说是明确的,以便将来进行维护.


Dhr*_*hah 6

我正在使用Factory pattens

  1. 当一个类不知道它必须创建哪个类对象时.

  2. 类指定其子类以指定要创建的对象.

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