- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我无法理解为工厂类定义抽象类/接口(interface)的作用,这是我在网络上的所有教程中经常看到的。有人可以阐明 CreatorInterface 的重要性吗? Reference UML Diagram of the Factory Pattern
要放入代码形式,这就是我所拥有的:
代码示例 1
// Product
public abstract class Vehicle
{
public string VehicleType { get; set; }
}
// Concrete Product
public class Bike : Vehicle
{
public Bike()
{
VehicleType = "Two Wheeler";
}
}
// Concrete Product
public class Car : Vehicle
{
public Car()
{
VehicleType = "Four Wheeler";
}
}
// Concrete Factory
public class VehicleFactory
{
public Vehicle GetVehicle(string VehicleType)
{
if (VehicleType == "Bike")
return new Bike();
else if (VehicleType == "Car")
return new Car();
else
return null;
}
}
// Client class
public class ClientClass
{
public void Main()
{
VehicleFactory VehicleFactoryObj = new VehicleFactory();
Vehicle BikeObj = VehicleFactoryObj.GetVehicle("Bike");
Vehicle CarObj = VehicleFactoryObj.GetVehicle("Car");
}
}
以上代码不包含“VehicleFactory”类的任何抽象类。但它工作正常。现在,为“VehicleFactory”添加抽象类的原因是什么?在我看来,添加一个抽象类对于抽象工厂方法来说是有意义的。 [如有错误请指正]
GoF 的定义:
Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses.
据我所知,该模式背后的核心问题陈述是您想要创建不同类的实例,而不向消费者公开创建逻辑。 如果我在这里遇到任何问题,请告诉我。由于我在网上看到的例子,我在这里也有点困惑。例如 Wiki 、Php 和 C# 示例。我可以消化 C# 示例中模式的要求,但不能消化 PHP 示例中的模式。无论如何,以下陈述将帮助您清楚地理解我的问题。
例如,我们的库中有两个车辆类 Bike 和 Car,它们都有车辆型号。自行车型号以“BK”开头,汽车型号以“CR”开头。现在,我们希望根据车辆型号返回任一类的实例,而不向客户端公开逻辑。 [注意这是一个更新的场景,我提出来是因为之前的场景在决定类时逻辑薄弱,并且在字符串的使用上造成了混淆]
因此我们可以创建一个车辆工厂类,它公开一个返回适当车辆实例的静态方法。
如果客户知道选择逻辑,那么我可能不需要模式本身。所以,可能看起来像:
代码示例 2
// Product
public abstract class Vehicle
{
public int NumberOfWheels { get; set; }
}
// Concrete Product
public class Bike : Vehicle
{
public Bike()
{
NumberOfWheels = 2;
}
}
// Concrete Product
public class Car : Vehicle
{
public Car()
{
NumberOfWheels = 4;
}
}
// Client class
public class ClientClass
{
public void Main()
{
String ModelNumber = "BK-125";
Vehicle CurrentVehicle;
if (ModelNumber.Contains("BK"))
{
CurrentVehicle = new Bike();
}
else if(ModelNumber.Contains("CR"))
{
CurrentVehicle = new Car();
}
}
}
工厂模式让我可以通过创建工厂来简单地向客户端隐藏创建逻辑。因此,客户现在只需要调用工厂的创建方法,他就会得到相应的类实例作为返回。现在代码看起来像这样。
代码示例 3
// Product
public abstract class Vehicle
{
public int NumberOfWheels { get; set; }
}
// Concrete Product
public class Bike : Vehicle
{
public Bike()
{
NumberOfWheels = 2;
}
}
// Concrete Product
public class Car : Vehicle
{
public Car()
{
NumberOfWheels = 4;
}
}
// Concrete Factory
public class VehicleFactory
{
public Vehicle GetVehicle(string ModelNumber)
{
if (ModelNumber.Contains("BK"))
return new Bike();
else if (ModelNumber.Contains("CR"))
return new Car();
else
return null;
}
}
// Client class
public class ClientClass
{
public void Main()
{
VehicleFactory VehicleFactoryObj = new VehicleFactory();
Vehicle BikeObj = VehicleFactoryObj.GetVehicle("BK-125");
Vehicle CarObj = VehicleFactoryObj.GetVehicle("CR-394");
}
}
现在问题来了关于抽象工厂类
添加抽象工厂类的一个好处是,我从讨论中了解到,客户端随后将能够覆盖“GetVehicle”方法来覆盖逻辑。对于他可能创建了更多车辆类别的情况,例如“卡车”。但即使在这种情况下,如果他想要重写所有三者(即 Bike、Car 和 Truck)的工厂方法,他也不会拥有完整的逻辑,因为创建 Bike 和 Car 的逻辑是用工厂方法编写的。尽管他将能够为他所有的新车辆类型创建新的逻辑。有人可以解释一下吗?
我想在这里说的更多一点是这个问题是关于工厂模式的,我知道抽象工厂模式需要一个抽象工厂,因为在抽象工厂模式中我们正在创建工厂的工厂 。但是在工厂模式中我们只有一个对象工厂,那么为什么我们需要一个工厂接口(interface)?
提前致谢!! :-)
最佳答案
是的,它有效,但并不理想。 VehicleFactory
有一个非常通用的方法,一旦您添加更多车辆,使用起来就会很麻烦,因为您需要一个非常长的方法来检查所有字符串。
假设您有 15 辆车。然后你需要一个非常长的方法来枚举所有选项并生成正确的汽车。这既不必要地慢,又容易出错,因为您很容易遗漏/删除某些内容,并且很难调试。一般来说,长方法是不好的代码味道。
此外,这需要您在每次添加继承Vehicle
的东西时编辑VehicleFactory
类。但是如果您的用户图书馆无权访问它但想从车辆继承?然而,通过定义一个抽象的 VehicleFactory
类,他可以从该类继承并定义他自己的工厂方法。
简而言之,抽象工厂方法只是让您的代码更易于扩展。
同时生成依赖于字符串的车辆是一个非常糟糕的主意;如果您使用大写或拼写错误怎么办?除此之外,它的速度很慢。最好有这样的东西。
public abstract class VehicleFactory
{
public abstract Vehicle GetVehicle(string VehicleType)
}
public class CarFactory : VehicleFactory
{
public override Vehicle GetVehicle(string VehicleType)
{
return new Car();
}
}
public class BikeFactory : VehicleFactory
{
public override Vehicle GetVehicle(string VehicleType)
{
return new Bike();
}
}
public class ClientClass
{
public void Main()
{
//Create Factories
BikeFactory BikeFactoryObj = new BikeFactory();
CarFactory CarFactoryObj = new CarFactory();
//create Vehicles from factories. If wanted they can be casted to the inherited type.
Vehicle VehicleObj=BikeFactoryObj.GetNewVehicle();
Bike BikeObj = (Bike)BikeFactoryObj.GetVehicle();
Car CarObj = (Car)CarFactoryObj.GetVehicle();
//They are all inherited from Vehicle so can be used in a list of Vehicles
List<Vehicle> Vehicles=new List<Vehicle>()
{
VehicleObj,
BikeObj,
CarObj
}
}
}
这里出现错误的机会要少得多,而且该类的任何用户都可以轻松调整。
关于c# - Creator 在工厂模式中的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46433489/
我正在尝试将 Parcelable 数据从一个 Intent 传递到另一个 Intent ,这是我得到的错误: 08-31 14:12:22.709: E/AndroidRuntime(9931):
我收到错误消息“Parcelable 协议(protocol)需要一个在类上名为 CREATOR 的 Parcelable.Creator 对象......”,但我确实有一个 Creator,但我不知
我喜欢 Qt Creator 中的深色“FakeVim”配色方案。然而,它只会使编辑器部分变暗,而其他一切都保持正常,这有点令人不安。有没有办法让 Qt Creator 全局使用这种黑暗方案? Vim
Qt Creator 中是否可以有构建后事件(如在 VC++ 中)?特别是,我想在构建可执行文件后将其复制到另一个文件夹。可以吗? 最佳答案 添加执行脚本以复制文件作为构建步骤,如下所示, 关于qt-
有没有办法在 Qt Creator 中获取打开文档的列表。 有时当 Qt Creator 崩溃并且在重新打开时无法恢复 session 时,在它崩溃之前有一个打开的文件列表会很方便。 最佳答案 不确定
Qt 似乎不像其他 IDE 通常那样在文件夹中构建文件,例如 netbeans 将头文件放在头文件夹中,将源文件放在源文件夹中等等。我已经看到这是在 Qt 中完成的,但我不知道为什么它不在我的电脑上。
我正在尝试创建一个 2 的上标,以显示用户在我的对话框中提供的字段之后的单位标签的平方。我在 Windows 上使用 Qt Creator v2.0.1。 QLabel 有一个文本字段和一个 text
我正在尝试更改 QT Creator 中的构建输出目录(即,我想输出到 ../../bin/debug 而不是输出到 ./debug)。我尝试通过项目模式编辑构建输出目录,但它是只读的。查看 .pro
如何在 QT Creator 中仅编译项目中的一个文件。 有快捷键吗? 例如,在 VS 中,您可以按 Ctrl F7 并编译当前的 cpp 文件。 最佳答案 现在可以做到这一点,至少是 Qt Crea
使用 Qt Creator 的 Memcheck 功能返回以下内容: valgrind: Bad option: --xml=yes, but no XML destination specified
我通常使用带有 cmake 的 Qt creator 来编程 C++ 项目。最近我读了很多关于介子的书,它很简单,我喜欢测试它。 This示例解释了如何设置介子。 在使用介子时,我仍然喜欢使用 Qt
我刚刚在我的机器上构建并安装了 QtQuick3D。我运行示例项目“立方体”。 它有效,我可以构建和执行它。它向我展示了一个可以用鼠标旋转的立方体。但是在 QML 编辑器中,我在所有 Viewport
作为一名已转向 Linux 的老 Borland C++ Bulder 程序员,我很高兴找到 QT 和 QT Creator。 但是我遇到了第一个障碍:我设计了一个带有一些控件的表单,并添加了一个菜单
Visual Assist X 为 Visual Studio 提供了一个很好的功能,称为 column indicator 。它在文本编辑器中的指定列上显示一条垂直线(我使用第 80 列)。这可以帮
这看起来应该很简单,但似乎没有一种方法可以像人们期望的那样做到这一点。 我在 qt Creator 中打开了两个单独的 C++ 项目,我想针对另一个项目中的一个项目进行包含/编译。 这是我的布局: p
问题: Qt Creator 是用 Qt Creator 构建的吗? 同样,Qt Designer 是用 Qt Designer 构建的吗? 顺便说一句,为什么有两个 Qt IDE?他们是竞争对手吗?
我坐在带有 Qt Creator v2.7 的 Ubuntu 12.04(也尝试过新版本,2.8 测试版)中,当我创建一个非 Qt 项目/普通 C++ 项目(CMake Build)时,一切似乎都很好
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: How to get Qt Creator to work with CDB? 我正在尝试将 Cdb 与 Qt C
Qt Creator 通常将注释着色为绿色,但我在 Qt 示例中看到了蓝色注释,而且 Qt Creator 似乎将所有以 //! 开头的注释着色为蓝色。 这是一个示例屏幕截图: 这是某种约定吗?蓝色代
我刚刚从英语下载站点http://qt.nokia.com/downloads上,在我的英语Windows 7系统上下载并安装了Qt Creator 1.3.1,显然,尽管帮助文件是英语,但Qt Cr
我是一名优秀的程序员,十分优秀!