我在Revit编程(开始)。为了简化我的问题,我有这个例子。
我有一个像OOP一样构建的绘图。图中的对象是C#对象。在这张图中,我有一个房间,有房间,房间里有其他物品,等等。所有这些不同的对象都可以嵌套得非常深。例如,这些物体中的一些包含螺钉。要找到房子里的所有螺丝,我必须搜索所有对象层次结构。但我怎么知道我找到了所有的螺丝,这需要很长时间。
如果我有发言权,每次我创建一个螺丝,我都把它放在一个自定义的集合中。但我无法控制这个过程。当我得到绘图时,它可以被绘制出来。
所以我的问题是:有没有办法根据它们是(一种)螺钉的事实来创建一组螺钉?
如果没有,这是OOP中的缺陷还是有充分的理由(安全性)?
提前致谢。
答案 0 :(得分:1)
这不是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)
{
}
}
}
对于一个简单的房子模型,这可以工作,但随着你的规模,你建模越来越多的细节(增加地板,天花板,sheetrock,螺柱,家具等)它不会很好地扩展,因为一切都保存在记忆中倍。如果你试图模拟一个复杂的CAD实际房屋,并确定一个材料清单,例如这个简单的实现可能会压倒任何机器。您想要弄清楚如何存储应用程序状态并检索应用程序状态,使其始终不需要在RAM中,但仍然允许查询和检查消费代码并不是更明智的。这是OOP的真正力量。
因此,如果您使用查询Sql数据库或CAD文件的方法替换内存集合和FindAll
方法实现,例如基本类设计(OOP部分)仍然可以保持完整。 OOP就是如何构建类型以最好地模拟问题域并组织实现。我可以向你保证,像AutoCAD这样的系统,实际上可以将房屋的设计转化为物料清单,在很大程度上依赖于OOP。