- 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/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!