c# - 可扩展的所有者界面

标签 c# oop design-patterns

我正在用 C# 设计一个简单的城市模拟,其中城市是一个类。城市有许多系统,例如道路系统和交通系统,它们也是类。 City 类聚合了上述类的实例。

class City: ICity
{
    RoadSystem.IRoadSystem       m_roadSystem;
    TrafficSystem.ITrafficSystem m_trafficSystem;
}

“系统”代码示例:

class SimpleRoadSystem : RoadSystem.IRoadSystem
{
    public SimpleRoadSystem(ICity owner)
    {
    }           
}

系统以及城市本身都有接口(interface),允许像往常一样进行替代实现。

我遇到的经典问题是实例化系统时。由于系统属于城市类,我可以将 ICity 实例传递给它们。系统类可以使用 ICity 接口(interface)从所属城市类中提取任何所需的数据。然而,这将 SimpleRoadSystem 限制为仅适用于城市。但实际上,道路系统是一个通用概念,它可以用于实现可能具有不同接口(interface)的地区或城镇的道路。基本上将 RoadSystem 的所有者绑定(bind)为一个城市,感觉受到限制。

因此另一个想法是在城市和 RoadSystem 之间建立一个 IRoadSystemOwner 接口(interface),该接口(interface)由城市实现。

class City: ICity, IRoadSystemOwner, ITrafficSystemOwner,......
{
    RoadSystem.IRoadSystem       m_roadSystem;
    TrafficSystem.ITrafficSystem m_trafficSystem;
}

class SimpleRoadSystem : RoadSystem.IRoadSystem
{
    public SimpleRoadSystem(IRoadSystemOwner owner)
    {
    }           
}

但这无法扩展。城市可以有任意数量的系统。它实际上是一个在运行时加载的列表。因此,如果城市需要 10 个不同的系统,则需要提前预测并实现 10 个不同的所有者界面!!

基本上,我试图弄清楚如何允许 RoadSystem 拥有的类拥有一个肯定具有已知所有者接口(interface)的所有者! 但不要通过不可扩展的继承来实现这个想法。这应该允许拥有的类从其所有者那里获取所需的信息。它应该具有良好的扩展性,因为一个城市可以拥有任意数量的系统,这些系统是在运行时根据数据决定的。

我认为动态转换或通用属性系统似乎有效。 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 类聚合了上述类的实例”是问题的根源。然后你想要一个区域类聚合相同的子系统,然后你重新考虑系统,当两个城市应该有相同的子系统时。这会导致以后出现许多复杂性问题。

当城市对子系统一无所知时,尝试以不同的方式重新思考这一点,因此它们是独立的,并且有一个类世界/执行上下文(它是所有这些的容器,并且了解每个人的一切) .

我没有看到任何关于你想如何使用它的线索,所以我不提供任何“真正的”方法。

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
    {
    }
}

关于c# - 可扩展的所有者界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51796689/

相关文章:

c# - 改进 Entity Framework 中的嵌套查询

c# - 如何在 WPF 中构建 "word-by-word"自动完成?

java - Java 中类的行

c# - 需要两个单例实例

c# - Jon Skeet 的 Singleton 说明

java - 在 Java 应用程序中跨层传递枚举

c# - DrawableGameComponent 作为库,内容如何处理?

c# - ASP.NET Web 应用程序消息框

perl - 为什么将 Perl OO 简单地用作数据封装技术?

Perl 封装类变量?