abstract class Vehicle { abstract void Move(); } class Car : Vehicle { override void Move() { // burn fuel // spin wheel } } class Plane : Vehicle { override void Move() { // suck air // burn fuel // spew jetstream } } class Rickshaw : Vehicle { override void Move() { // do one step // beg white master for money } }
abstract class Vehicle { Engine Engine { get { return engine; } set { if (value != null) { engine = value; } else { throw new ArgumentNullException(); } } } private Engine engine; protected Vehicle(Engine engine) { Engine = engine; } public void Move() { engine.Work(); } } class Car : Vehicle { Car() : base(new InternalCombustionEngine()) { } } class Plane : Vehicle { Plane() : base(new JetEngine()) { } } class Rickshaw : Vehicle { Rickshaw() : base(new Slave()) { } } abstract class Engine { public abstract void Work(); } class InternalCombustionEngine : Engine { public override void Work() { // burn fuel // spin wheel } } class JetEngine : Engine { public override void Work() { // suck air // burn fuel // spew jetstream } } class Slave : Engine { public override void Work() { // do one step // beg white master for money } }
... abstract class Vehicle<EngineT> : Vehicle where EngineT: Engine { protected Vehicle() : base(new EngineT()) { } } class Car : Vehicle<InternalCombustionEngine> { Car() : base(new InternalCombustionEngine()) { } } class Plane : Vehicle<JetEngine> { Plane() : base(new JetEngine()) { } } class Rickshaw : Vehicle<Slave> { Rickshaw() : base(new Slave()) { } } ...
If engine classes have constructors without parameters, then this should also be used by adding constraint new () to the EngineT type parameter. ... abstract class Vehicle<EngineT> : Vehicle where EngineT: Engine, new() { protected Vehicle() : base(new EngineT()) { } } class Car : Vehicle<InternalCombustionEngine> { } class Plane : Vehicle<JetEngine> { } class Rickshaw : Vehicle<Slave> { } ...
... abstract class Vehicle<EngineT> : Vehicle where EngineT : Engine { protected Vehicle() : base(Engine.GetFromWarehouse<EngineT>()) { } } ... abstract class Engine { abstract void Work(); private static readonly IDictionary<Type, Engine> warehouse = new Dictionary<Type, Engine> { { typeof(InternalCombustionEngine), new InternalCombustionEngine() }, { typeof(JetEngine), new JetEngine() }, { typeof(Slave), new Slave() }, }; static Engine GetFromWarehouse<EngineT>() where EngineT : Engine { return warehouse[typeof(EngineT)]; } } ...
As soalexmn accurately noted, for which he thanks, we just observed the Service locator pattern. As you can see, the farther into the forest, the less is left of the strategy. I 1 = new (); .(1); .(1); .(1);
Source: https://habr.com/ru/post/322762/
All Articles