简体   繁体   English

用于发送要添加到适当数据结构的对象的设计

[英]A design for sending objects to be added to the appropriate data structure

I have a class called DataStructures where I have a set of public static data structures that store objects. 我有一个名为DataStructures的类,其中有一组存储对象的public static数据结构。 To add an object to a data structures is an involved process requiring a number of checks to be carried out, processes to be remembered and data to be rearranged. 将对象添加到数据结构是涉及的过程,需要执行多个检查,要记住的过程和要重新排列的数据。 In another class called Foo , I need to add objects to the data structures. 在另一个名为Foo类中,我需要向数据结构添加对象。 I was thinking I can do this by making a method called ObjectFeed which would take an object and the object's label as parameters. 我想我可以通过创建一个名为ObjectFeed的方法来实现这一点,该方法将对象和对象的标签作为参数。 The label would tell the method which of the data structures the object should be added to. 标签将告诉方法应该将对象添加到哪个数据结构中。 I would also have a method called addObject which would take the object to append and the appropriate target data structure as parameters: 我还有一个名为addObject的方法,它将对象追加并将适当的目标数据结构作为参数:

Public Class DataStructures
{
    public static List<obj> object1Storage = new List<obj>();
    public static List<obj> object2Storage = new List<obj>();
    ...
}

Public Class Foo
{
    public void ObjectFeed(/* PARAMETERS */)
    {
      //Code that generates an object called inspectionObject
      //inspection object has an associated enum Type
        if(objectType == Type.Type1)
        {
             addObject(inspectionObject, DataStructures.object1Storage);
        }
        if(objectType == Type.Type2)
        {
             addObject(inspectionObject, DataStructures.object2Storage);
        }
        ...
    }

    private void addObject(obj inspectionObject, List<obj> objStorage)
    {
        objStorage.Add(inspectionObject);
        //And a lot more code
    }
}

Passing a public data structure as a parameter to a method that can just as well access that data structure directly doesn't feel correct. 将公共数据结构作为参数传递给一个方法,该方法也可以直接访问该数据结构,这种方法感觉不正确。 Is there a more clever and less intuitive way of doing this? 这样做有更聪明,更不直观的方式吗?

Edit: 编辑:

In the example I originally contrived, the ObjectFeed method served no apparent purpose. 在我最初设计的例子中,ObjectFeed方法没有明显的用途。 I rewrote the method to look more like a method from the real world. 我重写了这个方法,看起来更像是来自现实世界的方法。

Where is the object type coming from? 对象类型来自哪里? Passing a string value as a type of something is very rarely a good idea. 将字符串值作为一种类型传递很少是一个好主意。 Consider different options: 考虑不同的选择:

  1. Create an enum for these values and use this. 为这些值创建一个枚举并使用它。 You can always parse it from string or print it to string if you need to. 如果需要,您始终可以从字符串中解析它或将其打印为字符串。
  2. Maybe it makes sense to have a couple of specific methods: FeedObjectType1(object obj), etc.? 也许有一些特定的方法是有意义的:FeedObjectType1(object obj)等? How often will these change? 这些变化多久一次?

Its really difficult to give you a definite answer without seeing the rest of the code. 如果没有看到其余的代码,很难给出明确的答案。

Exposing public static lists from your DataStructures class is in most cases not a good design. 在大多数情况下,从DataStructures类公开公共静态列表并不是一个好的设计。 To start with I would consider making them private and providing some methods to access the actual functionality that is needed. 首先,我会考虑将它们设为私有,并提供一些方法来访问所需的实际功能。 I would consider wrapping the lists with the addObject method, so that you don't have to pass the list as an argument. 我会考虑使用addObject方法包装列表,这样您就不必将列表作为参数传递。 But again I am not sure if it makes sense in your case. 但是我再也不确定你的情况是否合理。

You seem to use DataStructures like some kind of global storage. 您似乎像某种全局存储一样使用DataStructures I don't know what you store in there so I'm going to assume you have good reasons for this global storage. 我不知道你在那里存储了什么,所以我将假设你有充分的理由来存储这个全局存储。

If so, I would replace each list with a new kind of object, which deals with additions of data and does the checks relevant for it. 如果是这样,我会用一种新的对象替换每个列表,该对象处理数据的添加并进行与之相关的检查。

Something like: 就像是:

interface IObjectStorage
{
   void Add(object obj);
   void Remove(object obj);
}

Each object storage type would derive from this and provide their own logic. 每个对象存储类型都将从中派生出来并提供自己的逻辑。 Or it could derive from Collection<T> or something similar if collection-semantics makes sense. 或者如果集合语义有意义,它可以从Collection<T>或类似的东西派生。 As your example is right now, I can't see the use for ObjectFeed, it serves as a fancy property accessor. 就像你现在的例子,我看不到ObjectFeed的使用,它作为一个奇特的属性访问器。

Selecting which property to access through a string sounds iffy to me. 选择通过字符串访问哪个属性听起来对我来说。 It is very prone to typos; 它很容易出现错别字; I would rather use Type -objects available from any object in C# through the GetType-method or typeof() construct. 我宁愿通过GetType-methodtypeof()构造使用C#中任何对象提供的Type -objects。

However. 然而。 The whole setup feels a bit wrong to me, DataStructures et al. 整个设置对我来说有点不对, DataStructures等。

First, testing your static class will be hard. 首先,测试你的静态类将很难。 I would pass around these stores to the types that need them instead. 我会将这些商店转移到需要它们的类型。 Replacing them with other stuff will also be hard, using interfaces will at least not tie you to a concrete implementation, but what if you want to use another location to store the objects in other code? 用其他东西替换它们也很难,使用接口至少不会将你绑定到具体的实现,但是如果你想使用另一个位置将对象存储在其他代码中呢? Your static class is no longer relevant and you'll need to change a lot of code. 您的静态类不再相关,您需要更改大量代码。

Maybe these things are out of your control, I don't know, the example code is a bit vague in that sense. 也许这些事情是你无法控制的,我不知道,在这个意义上,示例代码有点模糊。

As pointed out in other answers: 正如其他答案所指出:

  1. The public static List s are bad practice public static List是不好的做法
  2. Since the addObject method is the same for every data structure, it should be implemented as a data structure accessor. 由于addObject方法对于每个数据结构都是相同的,因此它应该实现为数据结构访问器。

To this end, I moved the instantiation of the data structures into Foo and moved the addObject method from Foo to a new class called StorageLibrary that more accurately represents the data structure architecture. 为此,我将数据结构的实例化移动到Foo中,并将addObject方法从Foo移动到名为StorageLibrary的新类,该类更准确地表示数据结构体系结构。

private class StorageLibrary 
{
    private List<obj> storedObjects = new List<obj>();
    public void addObject(obj inspectionObject)
    {
        storedObjects.Add(inspectionObject);
        //And a lot more code
    }
}

public class Foo : StorageLibrary
{
    //Declaration of libraries
    public static StorageLibrary storage1 = new StorageLibrary();
    public static StorageLibrary storage2 = new StorageLibrary();
    ...

    private void ObjectFeed(/* PARAMATERS */)
    {
        //generate objects

        if (objectType == Type.Type1)
        {
            storage1.addObject(inspectionObject);
        }
        if (objectType == Type.Type2)
        {
            storage2.addObject(inspectionObject);
        }
        ...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM