簡體   English   中英

如何實例化一個大的不可變類型?

[英]How to instantiate a large immutable type?

我有一個類型,有大約40個屬性(所有值類型),代表我的業務的一種交易。 此類的實例對應於我的數據庫中的一行。 我想保持我的類不可變,因為它只會用於讀取操作,但我不知道如何在初始化期間設置40個屬性。

通常我對不可變類型使用構造函數初始化,但我想避免編寫帶有40個參數的構造函數。 我的房產的安裝人員目前是私人的,但我願意以足夠的理由改變。 是否有一種常見的方法來處理這種情況或更好的方法來解決問題?

你的問題不是一個有40個參數的構造函數,而是一個有40個字段的類。

我建議打破這個。 是否有任何相關領域? 如果是這樣,將它們分組到一個公共對象(例如EmailInfo),然后讓你的大對象引用分組對象。

// Instead of this:
foo.EmailHeader
foo.EmailSubject
foo.Email...

// Do this:
foo.Email.Header
foo.Email.Subject

一旦你的類具有較少的直接屬性,創建一個獲取這些分組對象的構造函數並不是那么糟糕。

快點。 你提到你對象的setter是私有的。 如果是這種情況,那么您的對象不是不可變的(否則setter不存在)。 最好你的對象是只讀的。

對於一個真正的不可變對象,別無選擇,只能讓構造函數接受初始化對象所需的所有值。 減少構造函數中參數數量的最佳方法是將值分組為更大的對象,然后將這些對象傳遞給構造函數。 雖然我不會這樣做,除非這些值在邏輯上是相關的。

如果你的不可變類型確實需要40個值而且它們不相關,那么最好的方法是使用一個具有40個值的構造函數。 那還是進一步打破了大不可變對象。

我喜歡使用可變對象來實例化不可變對象的方法; 可變對象只是為了整理選項。 .NET框架中的一個例子是ProcessStartInfo

class XInfo {
  public int A;
  public int B;
}

class X {
  public X (XInfo i) {
    // you can transform the data/layout from i any way you need
    ..
  }
}

new X(new XInfo() {
  A = 42
})

雖然我會對'40屬性'保持緘默,但我發現上述方法效果很好。 另外一個好處是XInfoX使用的內部結構可以完全不同,只要您可以提供合理的映射。

如果我按照你的說法“但我不確定如何在初始化期間設置40個屬性。”,看來你的問題是一個具有太多字段/屬性的類。 似乎不是讓它變得不可變的問題,因為你已經知道如何做到這一點。

我會建議(像其他人一樣),Refactor和Extract Class。

作為替代方案,您可以使您的類派生自freezable ,我認為這可能是您正在尋找的解決方案。 您可以對對象進行Instatiate,設置值,然后將其設置為凍結。 一旦你將它設置為凍結,該類就是“只讀”。

我建議將參數放入一個或多個結構中,讓對象保存這些結構。 嵌套對象是可能的,但是會比嵌套結構增加更多的開銷。

作為替代方案,您可以使用所有屬性的“readonly mustoverride”版本創建一個抽象基類。 由此,派生出一個可變且不可變的對象類。 不可變的可以在其構造函數中接受基類,並使用所有readonly屬性來構建新對象。 可變類可以提供使用方法編寫屬性的方法,具有來自只讀版本的不同名稱的讀寫屬性等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM