工厂模式和策略模式有什么区别?
-
03-07-2019 - |
题
任何人都可以解释工厂模式和策略模式之间的区别吗?
对我来说,除了额外的工厂类(在工厂模式中创建产品对象)之外,两者看起来都相同
解决方案
工厂模式是一种创造模式。策略模式是一种操作模式。换句话说,工厂模式用于创建特定类型的对象。策略模式用于以特定方式执行操作(或操作集)。在经典示例中,工厂可能会创建不同类型的动物:狗,猫,虎,而策略模式将执行特定操作,例如,移动;使用Run,Walk或Lope策略。
实际上这两者可以一起使用。例如,您可能有一个用于创建业务对象的工厂。它可以使用基于持久性介质的不同策略。如果您的数据以XML格式存储在本地,那么它将使用一种策略。如果数据在另一个数据库中是远程的,那么它将使用另一个数据库。
其他提示
策略模式允许您以多态方式更改类的行为。
工厂模式允许您封装对象创建。
加里提出了一个很好的观点。如果您使用编码原则来抽象而不是“结核”然后很多模式开始看起来像主题的变化。
只是添加到tvanfosson所说的内容,很多模式在实现方面看起来都是一样的。也就是说,你可以创建一个接口,在你的代码中可能没有一个接口,然后创建一组该接口的实现。不同之处在于它们的用途以及它们的使用方式。
- 工厂(方法)模式。
仅创建具体实例。不同的参数可能会产生不同的对象。这取决于逻辑等。
- 战略模式。
封装执行操作的算法(步骤)。所以你可以改变策略并使用另一种算法。
虽然两者看起来非常相似,但目的却截然不同,一个目的是创建,另一个目的是执行操作。
所以。如果你的工厂方法是固定的,你可能会像这样:
public Command getCommand( int operatingSystem ) {
switch( operatingSystem ) {
case UNIX :
case LINUX : return new UnixCommand();
case WINDOWS : return new WindowsCommand();
case OSX : return new OSXCommand();
}
}
但假设您的工厂需要更先进或动态的创建。您可以向工厂方法添加一个策略并更改它,而无需重新编译,该策略可能会在运行时更改。
首先必须在简单工厂和抽象工厂之间做出区别。第一个是一个简单的工厂,你只有一个类作为创建对象的工厂,而后者则连接到工厂接口(定义方法名称),然后调用实现此接口的不同工厂。应该根据某些标准对同一方法进行不同的实现。例如,我们有一个ButtonCreationFactory接口,它由两个工厂实现,第一个是WindowsButtonCreationFactory(创建具有Windows外观的按钮),第二个是LinuxButtonCreationFactory(创建具有Linux外观的按钮)。所以这两个工厂都有相同的创建方法和不同的实现(算法)。您可以根据所需的按钮类型在运行时引用它。
例如,如果您想要具有Linux外观的按钮:
ButtonCreationFactory myFactory = new LinuxButtonCreationFactory();
Button button1 = myFactory.createButton(...);
或者如果你想要Windows按钮
ButtonCreationFactory myFactory = new WindowsButtonCreationFactory();
Button button1 = myFactory.createButton(...);
在这种情况下,它会产生一种策略模式,因为它区分了进行某些创建的算法。但是,它与语义不同,因为它用于OBJECT CREATION而不是操作算法。因此,基本上使用抽象工厂,您可以使用不同的策略创建对象,这使得它与策略模式非常相似。然而,AbstractFactory是创造性的,而战略模式是可操作的。实施明智,结果是相同的。
工厂(和工厂返回的FactoryMethod):
- 创作模式
- 基于继承
- Factory返回Factory Method(接口),然后返回Concrete Object
- 您可以将新的具体对象替换为接口,而客户端(调用者)不应该知道所有具体实现
- 客户端始终只访问界面,您可以在Factory方法 中隐藏对象创建详细信息 醇>
- 这是一种行为模式
- 它基于委托
- 通过修改方法行为来改变对象的内容
- 它用于在算法族之间切换
- 它在运行时更改对象的行为 醇>
策略模式:
示例:
您可以为特定项目(AirFare票证或ShoppingCart项目)配置折扣策略。在此示例中,您将在7月至12月期间为项目提供25%的折扣,在Jaunary - 6月期间为该项目提供无折扣。
相关帖子:
简单来说,策略模式更多的是运行时创建的行为,而您不关心实现类。另一方面,工厂是具体类实例的运行时创建,您可以使用实现的接口公开的任何行为(方法)。
延伸奥斯卡所说的并参考他的代码:
getCommand是Factory,UnixCommand,WindowsCommand和OSXCommand类是策略
我可能会对Oscar表示不满,因为他的工厂实现的例子非常紧密且非常封闭,难怪你的选择是策略模式。 Factory实现不应该依赖于实例化的任何固定数量的特定类,例如:
public Command getCommand( int operatingSystem ) {
return commandTable.get(operatingSystem);
}
...
public class WindowsCommand implements Command {
...
static {
CommandTable.getInstance().registerCommand(WIN_COMMAND_ID, new WindowsCommand());
}
}
我认为选择一个或另一个的最合适的标准主要是你用来命名你的类和方法的术语,考虑到我们都应该倾向于编程接口而不是类,还要关注目标:我们旨在确定哪些代码将在运行时执行。也就是说,我们可以通过使用任何两种模式来实现目标。
战略和工厂是不同的目的。在策略中,您可以定义方法,使用此模式可以交换行为(算法)。来到工厂有很多变化。但是来自GO4状态工厂的原始模式将对象的创建留给了子类。在工厂中,您将替换完整的实例,而不是您感兴趣的行为。通过这种方式,您将替换完整的系统而不是算法。
仅通过查看代码或分类,您无法理解差异。要正确掌握GoF模式,请查找它们的意图:
策略:“定义一系列算法,封装每个算法,并使它们可互换。策略允许算法独立于使用它的客户端。“
工厂方法:“定义用于创建对象的接口,但让子类决定实例化哪个类。 Factory Method允许类将实例化推迟到子类。“
这里有一个关于意图和这两种模式之间差异的详细解释:工厂方法和战略设计模式之间的差异
工厂模式是一种创建模式,使用指定的属性(行为)创建。而在创建后的运行时,你不会改变它的属性(行为)。所以,如果你需要不同的属性(行为),你必须删除对象并创建具有所需属性(行为)的新对象。这不是gud。 而在战略模式的情况下,你可以在运行时改变属性(行为)。