[英]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.