gpt4 book ai didi

c# - Creator 在工厂模式中的作用

转载 作者:行者123 更新时间:2023-12-05 06:38:20 25 4
gpt4 key购买 nike

我无法理解为工厂类定义抽象类/接口(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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com