如何在 C# 中建立功能组件关系
How to do functional-component relationship in c#
声明需要另一个 class 才能发挥作用的 class 的正确方法是什么?
例如,
public class Car
{
IEngine Engine { get; set; }
}
interface IEngine
{
void go();
}
public class DieselEngine
{
void go() {}
}
Car class 定义了对象的大部分功能。然而,一些功能被委托给一个子对象,它支持一些接口。
这样做正确吗?我应该将 Car 抽象化吗?还是引擎?或两者?也许我应该放弃 IEngine 并让 DieselCar 成为一个 subclass?
public class Car
{
abstract void go();
}
public class DieselCar : Car
{
void go() {}
}
还有哪些其他方法可以实现此目的?哪个最好?
你可以这样做:
public interface IEngine
{
void Start();
}
public class Engine : IEngine
{
public bool IsRunning { get; private set; }
public void Start()
{
// Do the common start here
IsRunning = true;
}
}
public class DieselEngine : Engine
{
public void Start()
{
// Do some deisel start stuff here
WaitForGlowPlug();
// Now start
base.Start();
}
private void WaitForGlowPlug()
{
// Do something
}
}
public class Car
{
private IEngine _engine;
public IEngine Engine
{
get { return _engine; }
set { if (value != null) _engine = value; }
}
public Car()
{
Engine = new Engine();
}
}
private static void Main()
{
Car dieselCar = new Car
{
Engine = new DieselEngine()
};
dieselCar.Engine.Start();
}
但实际上,您需要了解柴油车与其他汽车的不同之处。如果它不仅仅是引擎,那么您可能想要制作一个基础 Car class(或 ICar 接口)并拥有一个继承自 Car 的 DieselCar class。取决于您想要获得的粒度。
您正在寻找 Abstract Factory Design Pattern
派生 类 的问题是如果您有其他参数会怎样。例如,如果你有 2 门和 4 门汽车,通过推导你现在可能有 4 类:
- 柴油四门车身车
- GasFourDoorBodyCar
- DieselTwoDoorBodyCar
- GasTwoDoorBodyCar
您可以看到,这将很快失去对附加属性的控制。抽象工厂是一种为您的 类 指定不同的可交换组件的方法,这些组件是通过某种类型的构建器规范构建的。
保持简单。我发现构造函数是限制 class 的创建并向 class 的用户传达它需要的内容的最佳方式 'functional':
public Car(IEngine engine)
{
Contract.Requires(engine != null;
}
从这里开始,可以通过只读 属性 或经过验证的获取来进行控制。
我觉得你提的问题最有意思的一点是如何设计class,让你把它的需求表达的清楚直观。
声明需要另一个 class 才能发挥作用的 class 的正确方法是什么?
例如,
public class Car
{
IEngine Engine { get; set; }
}
interface IEngine
{
void go();
}
public class DieselEngine
{
void go() {}
}
Car class 定义了对象的大部分功能。然而,一些功能被委托给一个子对象,它支持一些接口。
这样做正确吗?我应该将 Car 抽象化吗?还是引擎?或两者?也许我应该放弃 IEngine 并让 DieselCar 成为一个 subclass?
public class Car
{
abstract void go();
}
public class DieselCar : Car
{
void go() {}
}
还有哪些其他方法可以实现此目的?哪个最好?
你可以这样做:
public interface IEngine
{
void Start();
}
public class Engine : IEngine
{
public bool IsRunning { get; private set; }
public void Start()
{
// Do the common start here
IsRunning = true;
}
}
public class DieselEngine : Engine
{
public void Start()
{
// Do some deisel start stuff here
WaitForGlowPlug();
// Now start
base.Start();
}
private void WaitForGlowPlug()
{
// Do something
}
}
public class Car
{
private IEngine _engine;
public IEngine Engine
{
get { return _engine; }
set { if (value != null) _engine = value; }
}
public Car()
{
Engine = new Engine();
}
}
private static void Main()
{
Car dieselCar = new Car
{
Engine = new DieselEngine()
};
dieselCar.Engine.Start();
}
但实际上,您需要了解柴油车与其他汽车的不同之处。如果它不仅仅是引擎,那么您可能想要制作一个基础 Car class(或 ICar 接口)并拥有一个继承自 Car 的 DieselCar class。取决于您想要获得的粒度。
您正在寻找 Abstract Factory Design Pattern
派生 类 的问题是如果您有其他参数会怎样。例如,如果你有 2 门和 4 门汽车,通过推导你现在可能有 4 类:
- 柴油四门车身车
- GasFourDoorBodyCar
- DieselTwoDoorBodyCar
- GasTwoDoorBodyCar
您可以看到,这将很快失去对附加属性的控制。抽象工厂是一种为您的 类 指定不同的可交换组件的方法,这些组件是通过某种类型的构建器规范构建的。
保持简单。我发现构造函数是限制 class 的创建并向 class 的用户传达它需要的内容的最佳方式 'functional':
public Car(IEngine engine)
{
Contract.Requires(engine != null;
}
从这里开始,可以通过只读 属性 或经过验证的获取来进行控制。
我觉得你提的问题最有意思的一点是如何设计class,让你把它的需求表达的清楚直观。