跨多个类更新集合

时间:2016-07-22 14:45:10

标签: c# design-patterns

我有大约500k项目的对象列表。对象类中包含大约100个(总)属性(嵌套或其他)。该模型的所有属性都是相互关联的。

我在各种类Enricher中为这些类丰富/赋值,因为每个值赋值都有它自己的大逻辑。

是跨多个类更新列表项的好方法吗?请注意,我必须将中间值存储在richhers中。

我有类似下面的课程设计

 class MyItem
    {
        public bool IsXyz { get; set; }
        public decimal Value { get; set; }
        public Tuple<string, string> MyTuple { get; set; }
        public double Rate { get; set; }
        //Like these around 100 properties
    }

    class Enricher1
    {
        public void Enrich(MyItem myItem)
        {
            myItem.IsXyz = true;
        }
    }

    class Enricher2
    {
        public void Enrich(MyItem myItem)
        {
            myItem.Value = 3M;
        }
    }

    class Enricher3
    {
        public void Enrich(MyItem myItem)
        {
            myItem.MyTuple = Tuple.Create("Test", "Test");
        }
    }

    class Enricher4
    {
        public void Enrich(MyItem myItem)
        {
            myItem.Rate = 300;
        }
    }

1 个答案:

答案 0 :(得分:0)

你的问题非常不清楚。因此,假设您有一个实例,例如:

List<MyItem> itemsList = listGetter.getList(); 

其中listGetter.getList()是您在获取列表时遗漏的任何代码,您应该将其列入其中。

  

我在各个类中为这些类丰富/赋值   称为Enricher,因为每个值赋值都有它自己的大逻辑

这是更新列表的一种奇怪方式。你不需要&#34;需要&#34; Enricher课程,因为几乎总是另一种做某事的方式。如果你需要做一些&#34;大逻辑&#34; (如果你想要准确地解决这个问题,为什么你不提供不那么模糊的评论?)在更新属性时,你可能需要将属性分组到类中,可以进行操作:

class MyItem {
    int widgetVolume { get; set { MadLogic.doMadLogic(); } } // throws TooMadForYouBroException
    int widgetDepth { get; set; }
    int widgetWidth { get; set; }
    int widgetHeight { get; set; }

    int wodgetVolume { get; set; }
    int wodgetDepth { get; set; }
    int wodgetWidth { get; set; }
    int wodgetHeight { get; set; }
}

变为

class MyItem {
    Widget widget { get; set; }
    Wodget wodget { get; set; }
}

class Widget {
    int widgetVolume { get; set; }
    int widgetDepth { get; set; }
    int widgetWidth { get; set; }
    int widgetHeight { get; set; }

    // Mad logic occuring here
    void UpdateHeight(int height) {
        this.widgetHeight = height;
        this.widgetVolumne = this.widgetHeight * this.widgetLength * this.widgetDepth;
    }

class Wodget {
    // Logic could also be in these as setter methods.
    int wodgetVolume { get; set; }
    int wodgetDepth { get; set; }
    int wodgetWidth { get; set; }
    int wodgetHeight { get; set; }

    void UpdateHeight(int height) {
        // Mad logic occuring here
        this.wodgetHeight = height;

        // Store some "intermediate" stuff, totally made up psuedo-code
        // I'm storing the height before the update, as an example
        Database db = SomeDbDriver.Connect("db-connection-string");
        db.SaveToTable("some-table", this.wodgetHeight);

        // Property updated, as well as updated side effects for other properties.
        this.wodgetVolumne = this.wodgetHeight * this.wodgetLength * this.wodgetDepth;
    }
}

更易于管理!注意MyItem现在必须只引用两个属性,并且所有疯狂的逻辑都整齐地隐藏在它自己的类中,而不是单个的,无法管理的,数千行的类。您甚至可以将这些类分成单独的文件。想象一下,找到导致&#34; WidgetHeightException&#34;的特定属性的位置是多么容易。是需要调试的时候,文件Widget.cs中只有一个类!

在集合上,如果它与itemsList一样,在顶部声明,则可以使用System.Linq。使用.Where()以及所有这些光荣的方法,可能会使用以下内容更新所有列表的属性:

itemsList.Select(c => {
    c.PropertyToSet = value; 
    return c; 
}).ToList();

但是,这实际上取决于你的意思&#34;更新列表&#34;。列表是什么?怎么声明?它存放在哪里?当类没有属性时,你的Enricher对象&#34;如何存储中间值&#34;

MyItem item = new MyItem();
Enricher enricher = new Enricher(item);

// What code can I call on the Enricher to return the value???