簡體   English   中英

Java中的null檢查重構

[英]null checking refactoring in java

我們有兩個類:

class Foo {
    private String a;
    private String b;
    private String c;
    ...
    getter...setter...
}

class Boo {
    private String a;
    private String b;
    private String c;
    ...
    getter...setter...
}

假設Foo和Bar不同,但是某些字段相同。

這是我想做的代碼:

  private void map(foo f) {
    Boo b = new Boo();
    if (f.getA() != null)  b.setA(f.getA());
    if (f.getB() != null)  b.setB(f.getB());
    if (f.getC() != null)  b.setC(f.getC());
    ....
  }

3個字段沒什么大不了的。

但是,如果有很多字段,那么也會有很多if()。

我想知道在Java或C ++中有一種不錯的自動方式和編程方式。

或者您可以使用類似的映射框架。 推土機: http : //dozer.sourceforge.net/

您將可以編寫如下代碼:

Mapper mapper = new DozerBeanMapper();
Boo destObject = new Boo();
mapper.map(foo, destObject);

...,它將把您的屬性從一個對象復制到另一個(使用反射)。

使用其他配置,您將能夠添加轉換邏輯或非平凡的映射規則(將Foo#prop1的值並將其放入Boo#prop2)或對象圖的深層副本。 還有很多。

您可以使用類似的功能接口和方法引用來刪除if語句。

static <X> void setIfNotNull(Consumer<X> setter, Supplier<X> getter) {
    X value = getter.get();
    if (value != null)
        setter.accept(value);
}

private void map(Foo f) {
    Boo b = new Boo();
    setIfNotNull(b::setA, f::getA);
    setIfNotNull(b::setB, f::getB);
    setIfNotNull(b::setC, f::getC);
}

std::optional

在C ++ 17中,這是超級可自動化的(在C ++ 17之前,您可以獲取optional類的任何實現,並使代碼以相同的方式工作)

class Container {
public:
    std::array<std::optional<std::string>, 3> three_string_nullables;
};

int main() {
    auto strings = std::array<std::optional<std::string>, 3>{};
    // fill the strings or don't
    auto container = Container{};
    container.three_string_nullables = strings;
}

為了概括這一點,您可以考慮將可選對象放入動態調整大小的容器中,例如std::vector

您可以將Java Reflection API用於此任務。 反射允許您獲取有關類的元數據(例如:類,方法等中的字段)。 除其他外,您可以調用類方法。 您可以從類中獲取所有的setter和getter,並且基於此信息可以進行必要的調用。

真正的答案是退后一步,看看引發您問題的需求。

您會發現,好的OO是關於創建模型或 抽象的 模型 ,它們代表您的代碼正在處理的“現實世界元素”。 以一種有用的方式。 從這個意義上講,良好的面向對象更多地是關於行為 (即方法),而不是狀態 (即字段)。

從那里開始:具有很多領域的類已經是第一個設計氣味。 然后,在大多數/所有這些領域中都使用吸氣劑/吸氣劑會使情況變得更糟

除此之外:當您有兩個班級A和B。A有5個字段,B有7個字段,...,您發現其中3個字段是“公共的” ... 真正的真實答案是:創建一個C類,包含這三個字段; ,然后將類型C的字段放入A和B。是的, 默認設置是在A和B中包含一個C字段-因為您更喜歡組合而不是繼承

所以,是的; 有一些框架對此有所幫助。 或者,您可以將字段重新組織到一個Map實例中。

但是(可能是自以為是):我認為您應該首先與一些真實的人交談,查看當前的解決方案並問自己:“我們是在這里進行真正的OO;還是我們的對象不過是記錄我們四處移動而后的過程代碼正在努力”。 換句話說-在這里問自己是否真的在做OOP。

也許您應該將String存儲在地圖中。

當您填充foo類時,可以使用insert進行操作。

然后,當您要相互復制時,需要迭代這些值。

如果類中有很多成員,則可以使用反射來復制字段。 這樣一來,您還可以正確地復制一個null值。 它包含很多易碎的代碼,因此只有在擁有許多成員的情況下它才有用。

暫無
暫無

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

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