我不明白为工厂类定义抽象类/接口的作用,这是我在网上所有教程中都看到的。请问有人能够解释一下CreatorInterface的重要性吗?{{link1:工厂模式的参考UML图表}}
为了以代码形式呈现,这是我的代码示例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的定义:
定义一个用于创建对象的接口,但让子类决定要实例化哪个类。工厂方法允许一个类推迟实例化它使用的子类。
就我所理解的而言,这种模式背后的核心问题陈述是,您希望创建不同类的实例,而不会将创建逻辑暴露给消费者。请告诉我是否在这里有任何错误。由于我在网络上看到的示例,我也有点困惑。例如,在Wiki上的PHP和C#示例中,我可以理解C#示例中的模式要求,但无法理解PHP示例中的要求。无论如何,下面的语句将帮助您清楚地了解我的问题。
例如,在我们的库中有两个车辆类Bike和Car,它们都有车型号。自行车型号以"BK"开头,汽车型号以"CR"开头。现在,我们希望根据车辆型号返回任一类的实例,而不向客户端公开逻辑。[注意 这是一个更新的场景,因为早期的场景决定类的逻辑较弱,导致对字符串的使用产生困惑]
因此,我们可以创建一个车辆工厂类,它公开一个静态方法,该方法返回适当的车辆实例。
如果选择逻辑要为客户端所知,则我可能不需要模式本身。所以,代码看起来像这样:
// 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();
}
}
}
工厂模式让我可以通过创建一个工厂简单地隐藏客户端的创造逻辑。因此,现在客户端只需要调用工厂的创建方法,就能得到相应的类实例。现在代码看起来像这样:
// 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”方法来覆盖逻辑。例如,他可能创建了更多的车辆类,比如“卡车”。但即使在这种情况下,如果他想要覆盖所有三个车辆类型(自行车、汽车和卡车)的工厂方法,他将没有整个逻辑,因为自行车和汽车的创建逻辑已经写在工厂方法中。尽管他将能够为他的所有新车辆类型创建新的逻辑。能否有人对此进行解释?
我想要提出的另一个观点是:这个问题涉及工厂模式,我确实理解抽象工厂模式需要一个抽象工厂,因为在抽象工厂模式中我们正在创建工厂的工厂。但在工厂模式中,我们只有一个对象工厂,那么为什么我们需要一个工厂的接口?
提前感谢! :-)
public Vehicle GetVehicle(string vehicleType)
。 - Yair Halberstadt