这是Factory Method创建模式吗?

use*_*985 43 c# design-patterns creation factory-pattern static-factory

我一直在使用工厂方法创建模式一段时间.我刚刚被告知这个:

public static class ScheduleTypeFactory
{
    public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType)
    {
        IScheduleItem scheduleItem = null;

        switch (scheduleType)
        {
            case ScheduleTypeEnum.CableOnDemandScheduleTypeID:
                {
                    scheduleItem = new VODScheduleItem();
                    break;
                }
            case ScheduleTypeEnum.BroadbandScheduleTypeID:
                {
                    scheduleItem = new VODScheduleItem();
                    break;
                }
            case ScheduleTypeEnum.LinearCableScheduleTypeID:
                {
                    scheduleItem = new LinearScheduleItem();
                    break;
                }
            case ScheduleTypeEnum.MobileLinearScheduleTypeID:
                {
                    scheduleItem = new LinearScheduleItem();
                    break;
                }
        }

        return scheduleItem;
    }
}
Run Code Online (Sandbox Code Playgroud)

不是我的"技术"主管的工厂方法创建模式,而没有告诉我为什么或给我她的解释.我很友好地要求解释,她告诉我她没有时间.我被告知要重命名它.如果我错了,那么毫无疑问我会接受我已经错误地实施了多年.这是你如何实现工厂方法创建模式?提前致谢.

THX*_*138 31

我同意将该方法称为"工厂方法",尽管该设计并非严格意义上的"工厂方法模式".
这是一个关键点(来自维基百科):

... Factory方法允许类将实例化推迟到子类."

由于您的类是静态的并且方法是静态的(因此是非虚拟的),因此不存在"延迟".

从概念上讲,还要注意,此实现虽然提供了封装,但不会解除/延迟任何决策.

话虽如此,同样的维基百科文章确实将此架构作为"工厂方法模式" 的变体.

摘要摘要:在我看来,这个片段不是"工厂方法OO设计模式" 的正确实现,因为它不满足"类子延迟实例化到子类".虽然,我个人可以自由地将此解决方案称为"工厂方法".

要使其成为真正的工厂方法模式,您需要允许子类重写该方法.即工厂类(ScheduleTypeFactory)需要是可扩展的(即非静态的),而GetScheduleItem需要是虚拟的.

  • 为什么正确的答案获得如此少的选票? (2认同)

And*_*are 29

当然看起来像我的工厂模式.我认为您的实施没有任何问题.

Factory方法模式:

工厂模式的本质是"定义用于创建对象的接口,但让子类决定实例化哪个类.Plant方法允许类将实例化延迟到子类."

这正是你在做的事情.

作为旁注:一个好的经验法则是,每当有人告诉你一些事情并且不能或不愿意为他们的陈述提供理由时,他们很有可能根本没有资格作出陈述.

  • "每当有人告诉你某事并且不能或不愿意为他们的陈述提供理由时,他们很有可能完全没有资格作出陈述"QFT (10认同)

Jar*_*Par 14

是的,这是工厂模式.我唯一的评论是你无法为你没有专门处理的枚举值而无声地失败.这可能是预期的,但我想在这样的陈述结尾添加以下内容

default:
  throw new InvalidOperationException("Invalid Enum Value");
Run Code Online (Sandbox Code Playgroud)

  • @Matt它真的取决于用法.但对我来说,如果我在工厂模式中调用一个函数,我完全期望它1)创建一个对象或2)失败并抛出.返回null是没有意义的,因为它给调用者没有关于操作失败原因的上下文.确实存在null有效且有意义的情况.这可能是其中之一.但我通常不希望从工厂模式返回null (8认同)

Ice*_*e09 12

您的代码片段在Head First Design Patterns中被称为"The Simple Factory"(第117页).Factory Method Pattern
的主要区别是ConcreteCreator(比较右上角的图表),这是一个简单的类.在"真实模式"中,工厂类是抽象的工厂类.所以,还有一个抽象层次.但是,对于许多用例,您的Simple Factory就足够了.

简易工厂 简易工厂http://yuml.me/7221a4c9 工厂方法模式 工厂方法模式http://yuml.me/3d22eb4e

  • 这是yUML:http://yuml.me它真棒,您通过文本生成UML(例如[Customer] +1 - >*[Order]),结果呈现为图像或PDF,带有这样的简单链接:http://yuml.me/5f1fa3ba,您可以在任何内容中包含,例如.<img rel="nofollow noreferrer" src ='http://yuml.me/5f1fa3ba'/> (9认同)

wil*_*ood 8

我认为它传统上被称为简单的工厂模式,以区别于"真正的" 抽象工厂模式.可能是因为您没有遵守某种内部命名惯例.她真的应该解释自己.


Pet*_*ter 8

你的领导是正确的 (对于格式化很抱歉,但是这个答案需要一些,以便在主线之间看到主要是白痴):既不是GOF书也不是Head First这是一种工厂方法.

GoF:

"定义用于创建对象的接口,但让子类决定实例化哪个类.Factory Method允许类将实例化延迟到子类."

在您的示例中,它不是决定的子类.

这些年来你有没有错误地实现它?不,你刚刚没有实现工厂模式,但有时也称为"简单工厂模式",这可能已经完成了工作.


Mar*_*ell 5

对我来说看起来像一个(基本)工厂......在许多工厂中,实现更复杂(可能涉及在运行时解析的类型),但这不是(AFAIK)的要求.我添加的唯一其他批评就是结合案例,如果你不认识那种类型就做一些更具戏剧性的事情......


cor*_*ick 5

我很惊讶很多人说这是工厂模式.(所以很可能我认为这是错误的,所以请让我知道.)

在我看来,你所拥有的只是设计的一部分.如果您从客户端调用它,它被称为"简单"工厂,但它并不是真正的设计模式.(别误会我的意思,我一直这样做).

工厂设计模式将声明您的工厂继承/实现抽象工厂/工厂接口.

然后,在需要使用工厂(客户端)的类中,将工厂类型设置为抽象/接口,创建具体工厂:ie - > IFactory factory = new ConcreteFactory();

然后,具体工厂将创建您的IScheduleItem(将其留给工厂以实际创建具体类型).

最后,我认为重点是疏松耦合.虽然一个"简单"的工厂松散地将产品的结构与客户结合在一起,但它并没有使工厂脱钩.工厂模式也使工厂脱钩.

再说一次,现在还早,我还没喝咖啡,而且我有一个讨厌的习惯,即发布绝对可怕的回答,错过了问题的全部内容.