这不是 OOP 的问题,但更可能是实现必须满足对房屋进行详细建模并列出其所有组成部分的要求。让我们看一个相当简单的实现,其中房子的每个部分都有一个父级,并且有一个子级集合,以及一个递归子级查找特定类型部分的方法:
class Program
{
static void Main(string[] args)
{
House h = new House();
Console.WriteLine("This house has {0} screws", h.FindAll<Screw>().Count());
}
public interface IHouseComponent
{
IHouseComponent Parent { get; }
IEnumerable<T> FindAll<T>() where T : IHouseComponent;
IEnumerable<IHouseComponent> Children { get; }
}
public abstract class HouseComponentBase : IHouseComponent
{
private List<IHouseComponent> _children = new List<IHouseComponent>();
protected HouseComponentBase(IHouseComponent parent)
{
Parent = parent;
}
protected void AddChild(IHouseComponent component)
{
_children.Add(component);
}
public IHouseComponent Parent { get; private set; }
public IEnumerable<IHouseComponent> Children { get { return _children; } }
public IEnumerable<T> FindAll<T>() where T : IHouseComponent
{
var list = new List<T>();
list.AddRange(_children.OfType<T>()); // add appropriate components in direct children
foreach (var node in _children)
list.AddRange(node.FindAll<T>()); // then add all components that are part of descendants
return list;
}
}
public class House : HouseComponentBase
{
public House()
: base(null)
{
// two room house
AddChild(new Room(this));
AddChild(new Room(this));
}
}
public class Room : HouseComponentBase
{
public Room(House parent)
: base(parent)
{
// 4 walls per room - no ceiling or floor
AddChild(new Wall(this));
AddChild(new Wall(this));
AddChild(new Wall(this));
AddChild(new Wall(this));
}
}
public class Wall : HouseComponentBase
{
public Wall(Room parent)
: base(parent)
{
for (int i = 0; i < 64; i++)
AddChild(new Screw(this));// each wall has 64 screws
}
}
public class Screw : HouseComponentBase
{
public Screw(IHouseComponent parent) // a screw can be part of any component
: base(parent)
{
}
}
}
对于一个简单的房子模型,这会起作用,但是随着您的缩放,您建模的细节越来越多(添加地板、天花板、石膏板、螺柱、家具等),它不会很好地缩放,因为所有内容都始终保存在内存中。例如,如果您尝试对实际房屋的复杂 CAD 绘图建模并确定物料清单,那么这个简单的实现可能会压倒任何机器。您想弄清楚如何存储应用程序状态和检索应用程序状态,这样它就不需要一直在 RAM 中,但仍然允许查询和检查它,而消费代码并不明智。这就是 OOP 的真正力量。
因此,如果您将内存中的集合和FindAll
方法实现替换为查询 Sql 数据库或 CAD 文件的方法,例如基本类设计(OOP 部分)仍然可以在很大程度上保持不变。OOP 就是关于如何构建类型以最好地建模问题域并组织实现。我可以向您保证,像 AutoCAD 这样的系统实际上可以将房屋设计转变为材料清单,这在很大程度上依赖于 OOP。