c# - 可扩展的所有者界面
问题描述
我正在用 C# 设计一个简单的城市模拟,其中城市是一个类。这座城市有许多系统,例如 RoadSystem 和 TrafficSystem,它们也是类。City 类聚合了上述类的实例。
class City: ICity
{
RoadSystem.IRoadSystem m_roadSystem;
TrafficSystem.ITrafficSystem m_trafficSystem;
}
示例“系统”代码:
class SimpleRoadSystem : RoadSystem.IRoadSystem
{
public SimpleRoadSystem(ICity owner)
{
}
}
系统以及城市本身都有接口,可以像往常一样允许替代实施。
我遇到的经典问题是在实例化系统时。由于系统归城市类所有,我可以将 ICity 实例传递给它们。系统类可以使用 ICity 接口从拥有的城市类中提取任何所需的数据。然而,这将 SimpleRoadSystem 与城市联系在一起。但实际上道路系统是一个通用的概念,它可以用于实现一个区域或一个城镇的道路,可能有不同的接口。基本上将 RoadSystem 的所有者绑定为仅是一个城市,感觉有限制。
所以另一个想法是在city和RoadSystem之间建立一个IRoadSystemOwner接口,由City实现。
class City: ICity, IRoadSystemOwner, ITrafficSystemOwner,......
{
RoadSystem.IRoadSystem m_roadSystem;
TrafficSystem.ITrafficSystem m_trafficSystem;
}
class SimpleRoadSystem : RoadSystem.IRoadSystem
{
public SimpleRoadSystem(IRoadSystemOwner owner)
{
}
}
但这并不能扩展。城市可以有任意数量的系统。它实际上是一个在运行时加载的列表。因此,如果城市有它需要的 10 种不同的系统,则需要事先预测并实施 10 种不同的所有者界面!
基本上我想弄清楚如何让 RoadSystem 拥有的类拥有一个拥有已知所有者接口的所有者!但不要通过不可扩展的继承来实现这个想法。这应该允许拥有的类从其所有者那里提取所需的信息。它应该可以很好地扩展,因为一个城市可以拥有在运行时根据数据决定的任意数量的系统。
我认为动态转换或通用属性系统的方式似乎有效。RoadSystem 类可以尝试将所有者实例转换为 ICity、ITown 或 IRegion 并查看哪个成功。或者所有者有一个 getProperty(key) 函数,它返回一个通用对象引用,可以将其转换为具体类以获取实际数据,例如:
object obj = owner.getProperty("Map")
IMap map = obj as IMap;
if (map == null)
{
throw new System.ArgumentException("The map could not be retrieved from owner", "original");
}
除了使用动态转换之外,还有其他方法吗?
解决方案
正如我所见,“City 类聚合了上述类的实例”是这里问题的根源。然后你想要一个区域类来聚合相同的,然后你重新考虑系统,当两个城市应该有相同的子系统时。这将在以后导致许多复杂性问题。
当城市对子系统一无所知时,尝试以不同的方式重新考虑这一点,因此它们是独立的,并且有一个类 World/Execution 上下文(这是所有这些的容器,并且知道关于每个人的一切)。
我看不出您想如何使用它的任何线索,因此我不提供任何“真实”方法。
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
public class World
{
public List<ICity> Cities { get; set; }
public List<IRegion> Regions { get; set; }
public List<IRoadSystem> RoadSystems { get; set; }
public List<ITrafficSystem> TrafficSystems { get; set; }
//any other systems you like
public void AddRoadSystemToCity(IRoadSystem system, ICity city)
{
}
public IRoadSystem GetRoadSystem(ICity city) //or any other rule we would like to use later
{
throw new NotImplementedException();
}
}
public interface IRegion
{
}
public interface ITrafficSystem
{
}
public interface IRoadSystem
{
}
public interface ICity
{
}
}
推荐阅读
- javascript - 无法在本机反应中更改事件触发器的状态
- java - 自定义类级别验证 - 创建注释
- c++ - 使用定时器重复调用函数
- javascript - Issue with bootstrap modal
- python - (BAD_COLUMN_NAME):字形指的是不存在的列名,散景
- loops - 如何使用嵌套的 for 循环来增加单个变量中的值并随时间移动到下一个
- javascript - 为什么 django 上的“关注”按钮不起作用?
- android - 使用直接标记化的 Google Pay 付款集成
- python - 使用 csv 文件从考勤日志报告中过滤时间
- python - 启动 VSCode 时自动激活 conda 环境