我有遗留代码和我的任务来重构它。
所以我有这样的事情:
...
if (param == "car")
result = new Car();
else if (sectionType == "bus")
result = new Bus();
else if (sectionType == "motorcycle")
result = new Motorcycle();
...
我认为代码不具备生产力和支持。
问:我的目标是找到更好的设计解决方案。
提前谢谢
答案 0 :(得分:3)
你所拥有的是一个工厂,所以你可以将逻辑封装在工厂类中,以使其更清洁,更易于维护。
如果工厂类知道它需要创建的所有类型,那么它可以负责所有构造函数。但是,如果一个或多个车辆类未知,您可以为其提供某种注册方法,以便其他代码可以为其添加更多构造函数。
这是一个例子。让我们假设我们有:
public abstract class Vehicle {}
public class Car : Vehicle {}
public class Bus : Vehicle {}
然后你可以这样写一个工厂:
public sealed class VehicleFactory
{
public VehicleFactory()
{
RegisterConstructor("car", () => new Car());
RegisterConstructor("bus", () => new Bus());
}
public void RegisterConstructor(string name, Func<Vehicle> func)
{
_map.Add(name, func);
}
public Vehicle Create(string name)
{
if (_map.TryGetValue(name, out Func<Vehicle> create))
return create();
throw new InvalidOperationException($"No such vehicle name: {name}");
}
readonly Dictionary<string, Func<Vehicle>> _map = new Dictionary<string, Func<Vehicle>>();
}
现在假设您要支持工厂不了解的其他类型Motorcycle
。您仍然可以通过让其他代码调用RegisterConstructor()
来添加它来处理它,如下所示:
class Motorcycle : Vehicle { }
class Program
{
static void Main()
{
var factory = new VehicleFactory();
factory.RegisterConstructor("motorcycle", () => new Motorcycle());
var bike = factory.Create("motorcycle");
var car = factory.Create("car");
}
}
请注意,在实际代码中,您可能希望将具体类抽象为抽象基类或接口,但对于此示例,只使用具体类更简单。
另外,理想情况下,您希望通过VehicleFactory
构造函数而不是使用RegisterConstructor()
方法来使用依赖项注入:
public sealed class VehicleFactory
{
public VehicleFactory(params (string name, Func<Vehicle> constructor)[] constructors)
{
_map.Add("car", () => new Car());
_map.Add("bus", () => new Bus());
foreach (var c in constructors)
{
_map.Add(c.name, c.constructor);
}
}
public Vehicle Create(string name)
{
if (_map.TryGetValue(name, out Func<Vehicle> create))
return create();
throw new InvalidOperationException($"No such vehicle name: {name}");
}
readonly Dictionary<string, Func<Vehicle>> _map = new Dictionary<string, Func<Vehicle>>();
}
您可以这样使用:
class Motorcycle : Vehicle {}
class MilkFloat : Vehicle {}
class Program
{
static void Main()
{
var factory = new VehicleFactory(
("motorcycle", () => new Motorcycle()),
("milk float", () => new MilkFloat())
);
var bike = factory.Create("motorcycle");
var car = factory.Create("car");
var milk = factory.Create("milk float");
}
}