如何存储/处理c#中其他类可用的数据

Vah*_*hid 4 c# static class

我正在写一个CAD程序.假设我在输入类中,该类从文本文件中读取各种数据并创建大量列表/字典......这些数据需要通过其他类中的其他方法进行修改.现在这是我到目前为止的方式:

我有一个静态类:Building.cs当我创建/或加载项目时,此类包含所有数据,如列,梁,点等列表.所有这些都存储为私有字段.我可以使用类的公共方法(如GetColumns或GetPoints)访问这些...

现在我也有非静态类.它们包含2-3种公共方法.并在建筑物的各个部分做一些事情.

public static class Building
{
    private static List<Column> columns;
    private static List<Beams> beams;
    private static List<Points> points;

    public static List<Column> GetColumns() 
    {
        return Columns;
    }
}

public class ColumnsService()
{
    private List<Columns> columns;
    public GroupColumns(List<Columns> columns)
    {
        this.columns = columns;
    }

    public void Group()
    {
        // group columns
    }
}

var columns = Building.GetColumns();
var columnsService = new ColumnsService(columns);
columnsService.Group();
Run Code Online (Sandbox Code Playgroud)

我想知道这是要走的路吗?我还能如何存储数据.在整个程序的整个生命周期中,大多数类都需要访问数据.什么是最佳实践.

Dav*_*vid 7

什么,在语义上,是一个Building

对我来说,这个名字意味着它是一个结构的实例.在整个业务领域中,可以存在许多"建筑物",并且在任何给定时刻,一个人正在与其中一个进行交互.

如果是这样的话,那么制作它似乎不直观static.如果有多个,则它应该是实例模型.它将包含描述它的属性和与之交互的操作.正在建模的业务领域应该在考虑其他对象如何与之交互之前驱动该对象的结构.

所以我们假设我们将它作为实例模型:

public class Building
{
    // attributes and operations
}
Run Code Online (Sandbox Code Playgroud)

然后,正如您所问,其他对象如何与之交互?

取决于互动.

假设一个物体需要以某种方式"渲染"建筑物.让我们称它为BuildingPrinter缺乏更好的术语.显然它需要Building"打印".所以它需要一个操作:

public class BuildingPrinter
{
    public void Print(Building building)
    {
        // implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

或许你有一个以某种方式"包裹"建筑物的物体.没有建筑物就无法有意义地存在的东西,无论所执行的操作如何.我想不出那个特定的业务领域,所以让我们称之为BuildingWidget.由于它需要一个建筑物,它需要一个:

public class BuildingWidget
{
    private Building currentBuilding;

    private BuildingWidget() { }

    public BuildingWidget(Building building)
    {
        currentBuilding = building;
    }
}
Run Code Online (Sandbox Code Playgroud)

关键是,从构建整个域的模型的角度来看,如果需要某些东西,则必须提供它.这些模型不应该出现在某个全局数据存储中,与该数据存储紧密耦合,以获得所需的内容.这称为依赖性倒置原则.

但是,编排这些模型的交互的消费代码会在哪里获得Building?有很多可能的解决方案.

两种常见的模式是拥有静态工厂或存储库.例如:

public class BuildingFactory
{
    public static Building FetchBuilding(int buildingId)
    {
        // implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

该工厂可能具有静态缓存的构建对象.构建本身不是静态的,但出于性能原因,它的一个实例是静态缓存的,因此不会从后备数据存储(例如数据库)中不断地重新获取它.您还可以添加方法来使缓存无效并重新获取,或将该逻辑封装到工厂本身(例如,总是在5分钟后或10次访问后重新获取或其他一些规则).(在幕后,这个工厂甚至可以使用一个存储库,如下所示,重新获取该实例.在这种情况下,你猜BuildingRepository对了,BuildingFactory构造函数需要一个.)

如果您有理由将构造函数设置为私有,则此工厂对象也可能负责基于某些规范创建Building构建.

或者,要从数据重新获取,请考虑一个存储库:

public class BuildingRepository
{
    public Building GetBuilding(int buildingId)
    {
        // fetch from database
    }

    public Building SaveBuilding(Building building)
    {
        // save to database, return updated version
    }
}
Run Code Online (Sandbox Code Playgroud)

然后整个域中的其他代码(包括消费代码)可以使用这些对象来获取/保存建筑物.工厂是静态的,因此可以在任何地方调用.存储库是实例,但不需要全局不同,因此可以在任何地方实例化(或从依赖注入容器中拉出).