C# 重构如果。。。其他设计
我有遗留代码和重构它的任务C# 重构如果。。。其他设计,c#,design-patterns,architecture,C#,Design Patterns,Architecture,我有遗留代码和重构它的任务 存在基本类(即车辆) 它的继承人(汽车、公共汽车、摩托车等) 服务,必须通过参数选择合适的继承人并将其变大 所以我有这样的想法: public sealed class VehicleFactory { public VehicleFactory() { RegisterConstructor("car", () => new Car()); RegisterConstructor("bus", () =>
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>>();
}
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");
}
}
我认为代码是无效的,并且不受支持
Q:我的目标是找到更好的设计解决方案
Thx预先您拥有的是一个工厂,因此您可以将逻辑封装在一个工厂类中,以使其更干净、更易于维护 如果工厂类知道它需要创建的所有类型,那么它可以负责所有构造函数。但是,如果它不知道一个或多个车辆类,则可以为其提供某种注册方法,以便其他代码可以向其添加更多构造函数 这里有一个例子。假设我们有:
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>>();
}
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");
}
}
注意,在实际代码中,您可能希望将具体类抽象为抽象基类或接口,但在本例中,只使用具体类更简单
此外,理想情况下,您希望通过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>>();
}
这里有一个工厂,因此可以将逻辑封装在工厂类中,以使其更干净、更易于维护 如果工厂类知道它需要创建的所有类型,那么它可以负责所有构造函数。但是,如果它不知道一个或多个车辆类,则可以为其提供某种注册方法,以便其他代码可以向其添加更多构造函数 这里有一个例子。假设我们有:
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>>();
}
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");
}
}
注意,在实际代码中,您可能希望将具体类抽象为抽象基类或接口,但在本例中,只使用具体类更简单
此外,理想情况下,您希望通过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>>();
}
使用接口可能是一种选择……但我不知道它如何帮助我。我发现了如何以更清晰的方式重写当前的实现。感谢您的关注,我投票决定将这个问题作为离题题结束,因为这是一个回顾,因此应该转到每个问题,附带的代码示例可以被视为回顾。我认为这是一个常见的问题,有一些“模式”可以解决这种问题problems@AllmanTool但您并不是在寻找解决特定问题的方法,您只是在寻找如何最好地解决一般问题的指导,而是使用特定的代码片段。所以这并不是这个网站的重点。使用界面可能是一种选择……但我知道它如何帮助我。我发现了如何以更清晰的方式重写当前的实现。感谢您的关注,我投票决定将这个问题作为离题题结束,因为这是一个回顾,因此应该转到每个问题,附带的代码示例可以被视为回顾。我认为这是一个常见的问题,有一些“模式”可以解决这种问题problems@AllmanTool但您并不是在寻找解决特定问题的方法,您只是在寻找如何最好地解决一般问题的指导,而是使用特定的代码片段。所以这并不是这个网站的重点。