这是工厂方法创build模式?

现在我一直在使用工厂方法创build模式。 我刚刚才被告知这个:

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

不是我的“技术”领导的工厂方法创造模式,也不告诉我为什么或给我她的解释。 我恳求一个解释,她告诉我,她没有时间。 我被告知只是重命名它。 如果我错了,那么我肯定会接受这个问题。 这是你如何实现工厂方法创build模式? 提前致谢。

我同意把这个方法称为“工厂方法”,虽然这个devise不是严格的“工厂方法模式”。
这里是一个关键点(来自维基百科):

Factory方法让类将实例化推迟到子类。

由于你的类是静态的,方法是静态的(因此是非虚拟的),所以没有“延迟”的可能。

从概念上讲,也请注意,这个实现虽然提供了封装,但不会解耦/延迟任何决定。

话虽如此,维基百科的文章也将这个模式作为“工厂方法模式”的一个变体

总结总结:在我看来,这个片段并不是“工厂方法OOdevise模式”的正确实现,因为它不能满足“类将类实例推迟到子类”。 虽然,我个人会自由地将这个解决scheme称为“工厂方法”。

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

当然看起来像我的工厂模式。 我没有看到你的实现有什么问题。

从工厂方法模式 :

Factory Pattern的本质是“定义一个创build对象的接口,但让子类决定实例化哪一个类。Factory方法让类将实例化推迟到子类。

这正是你在做什么。

作为一个附注:一个好的经验法则是,每当有人告诉你某件事情,不能或不愿意为他们的陈述提供一个理由时,他们根本就没有资格发言。

是的,这是一个工厂模式。 我唯一的意见就是你默默地失败了你不具体处理的枚举值。 这可能是可以预料的,但我希望在这样的陈述结尾添加以下内容

 default: throw new InvalidOperationException("Invalid Enum Value"); 

你的代码片段就是Head First Design Patterns被称为“简单工厂”(p.117)。
工厂方法模式的主要区别是ConcreteCreator (比较右上angular的图),这是一个简单的类。
在“真实模式”中,工厂类是抽象的工厂类。 所以,还有一个抽象层次。 但是,对于许多用例,您的简单工厂就足够了。

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

我认为传统上被称为简单的工厂模式,以区别于“真正的” 抽象工厂模式。 这可能是因为你没有遵守某种内部命名的做法。 不过她真的应该自己解释一下。

你的主angular是正确的 (对格式不好意思,但是这个答案需要一些,才能在主线是白痴的主线之间看到):既不是GOF书也不是Head First这是一种工厂方法。

GoF:

“定义一个创build对象的接口,但让子类决定实例化哪个类。 工厂方法让类将实例化推迟到子类。

在你的例子中,它不是一个正在决定的子类

这些年你有没有错误地实施? 不,你只是没有实现工厂模式,但有时被称为“简单工厂模式”,可能已经完成了这项工作。

看起来像一个(基本)工厂对我来说…在许多工厂的实现是更复杂(可能涉及在运行时parsingtypes),但这不是(AFAIK)的要求。 我唯一要加的其他批评就是把案件结合起来,如果你不认识这种types的话,做一些更具戏剧性的事情。

我很惊讶,这是工厂模式。 (所以有机会,我想这个错误,所以请让我知道。)

在我看来,你所拥有的仅仅是devise的一部分。 如果你从你的客户端调用它,它被称为“简单”的工厂,但它不被认为是一个devise模式。 (不要误解我的意思,我一直这么做)。

工厂devise模式将声明你的工厂inheritance/实现了一个抽象的工厂/工厂接口。

然后,在需要使用工厂(客户端)的类中,将工厂的types设置为抽象/接口,创build一个具体工厂:即 – > IFactory factory = new ConcreteFactory();

然后具体的工厂会创build你的IScheduleItem(把它留给工厂去实际创build具体的types)。

最后,我认为整个问题是关于松耦合。 虽然一个“简单”的工厂松散地耦合来自客户的产品的build设,但并没有使工厂脱钩。 工厂模式也使工厂分离。

再说一遍,我还没有喝咖啡,而且我有一个很糟糕的习惯,就是发表了绝对可怕的回答,这个回答错过了整个问题的关键。

那么,维基百科说这是一种工厂方法:

 public class ImageReaderFactory { public static ImageReader getImageReader( InputStream is ) { int imageType = figureOutImageType( is ); switch( imageType ) { case ImageReaderFactory.GIF: return new GifReader( is ); case ImageReaderFactory.JPEG: return new JpegReader( is ); // etc. } } } 

看起来像一个工厂模式给我。 告诉你的技术主pipe你没有时间来解释为什么她错了。

这是工厂模式,但不一定是最易维护的变体。 一个更易维护的变 IScheduleItemScheduleTypeEnum值和IScheduleItem实际具体子types之间维护某种forms的全局映射 – 这样,可以用查找映射来replaceswitch语句。

为什么它更可维护? 因为子类作者可以在它们派生类的位置向映射添加对,而不是在GetScheduleItem()工厂函数本身中添加对。 因此后者不需要更新; 它始终是最新的。

在C ++中,你可以使用全局的std::map来实现这一点 – 对于每一个具体的子类,子类的作者添加了一个虚拟的全局variables,它实际上只是在它的构造函数中注册类(通过添加到地图)程序启动时间。 我敢肯定,有一个方便的方法来在C#中做同样的事情。

(C ++ guru Herb Sutter 在这里有一个有趣的描述 ,但它相当C ++ – 沉重。)

这确实是一个“工厂”,因为你有一个方法返回基于某种逻辑的IScheduleItem的特定实例; 但是,考虑到您正在使用switch语句,它可能不是最好的实现或最可维护的实现。

是的,这是工厂模式。 你的技术领导是错误的。

看起来像一个基本的工厂模式给我。 我很好奇听说为什么你的技术主pipe不认为这是一种模式。

我也很失望,她不会花时间来解释事情。 作为一个团队的技术主pipe之前,花时间来解释你的决定是很有趣的。

这是工厂的方法模式,至less根据维基百科: http : //en.wikipedia.org/wiki/Factory_method_pattern

技术领导可能认为Factory模式是replace同一对象中的构造函数,而不是返回子类,或者只返回超类的子类,而不是从不相关的对象中返回。 这是错的,但这可能是这个想法。

维基百科列举您的模式作为一个例子的事实表明,这是一个正确的工厂模式。 这些模式的定义是为共同的解决scheme提供一个共同的语言,很明显,如果维基百科把这个作为一个例子,它就是通用语言的一部分。 关于“工厂模式”在某种抽象意义上的学术争论,忽略了模式的要点。

立即收回权力! 只要从措辞中删除“types”即可。 ScheduleFactory FTW。 等等,这是“时间表”还是“时间表”的工厂? 如果是计划项目,那么工厂应该被称为“ScheduleItemFactory”。 performance力!

工厂模式的最简单的解释是我从模式和实践课学到的,如果你依靠另一个类来创build你的类的实例,那么你使用的是工厂模式。

当然,通常你想通过使你的类抽象或者一个接口来添加一个间接层。

这是非常简单的视图,但无论如何,您正在使用工厂模式。

你的技术是正确的重命名的方法:

 public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) 

该方法的作用是不去获取东西,是创造一些东西。 你如何决定应该创build哪个scheduleType? 似乎逻辑应该被封装,而不是types的开关。

另外为什么在课堂上的静态 ? 你从哪里使用它?

 public class ScheduleTypeFactory { public static IScheduleItem createScheduleFrom(ScheduleTypeEnum scheduleType) { switch (scheduleType) { case ScheduleTypeEnum.CableOnDemandScheduleTypeID: case ScheduleTypeEnum.BroadbandScheduleTypeID: return new VODScheduleItem(); case ScheduleTypeEnum.LinearCableScheduleTypeID: case ScheduleTypeEnum.MobileLinearScheduleTypeID: return new LinearScheduleItem(); } raise InvalidSchedule; } } 

那是教科书工厂模式。

有些文字称之为简单工厂模式,但是我从来没有看到“简单”意思的任何标准。

在我的实践中,一个工厂模式是任何智能创build一个具体的类相应的接口。

但是,为什么要争取技术领先的方法。 重命名它,继续你的生活。