Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重构如果。。。其他设计_C#_Design Patterns_Architecture - Fatal编程技术网

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但您并不是在寻找解决特定问题的方法,您只是在寻找如何最好地解决一般问题的指导,而是使用特定的代码片段。所以这并不是这个网站的重点。