[英]How to Consolidate Many Classes and Avoid instanceof?
我正在幫助開發的程序應該輸出幾個動態生成的問題供用戶回答。 問題具有不同的類型,並且具有相應的類Constraint
,它們用用戶給定的信息填充。 我的問題是如何為不同的約束創建統一的行為。
---->Constraint<--------------------
| | |
FConstraint PConstraint TConstraint
| |
UConstraint AConstraint
基類Constraint
為空,TConstraint也是如此。
UConstraint
, PConstraint
和AConstraint
共享三個變量。 但是, UConstraint
和AConstraint
還有一個PConstraint
沒有的附加變量。
我覺得我正試圖用一些鉗子敲打磚牆。 我的想法是為約束提供帶有簽名的抽象方法:
// All answers are of type string.
abstract void setValue(string variable, string answer);
這是由每個Constraint
子類實現的。 但是,傳遞一個字符串來確定要設置哪個變量似乎容易出錯,而且代碼味道也差不多。
第二種選擇是將三個相似的變量移動到Constraint中,但這仍然留給UConstraint, AConstraint
以及我可能需要設置的額外信息。 TConstraint
不需要任何這些,這沒有任何幫助。
我現在的蠻力“擰這個設計。” 解決方案是一個湯的instanceof
,我在其中檢查並填寫缺少的特定於約束的信息。
Object constraint = item.getConstraint();
if (constraint instanceof AConstraint) {
AConstraint constraint = (AConstraint) constraint;
if (constraint.getValue() == null) {
constraint.setValue(string);
} else if (constraint.getKey() == null) {
constraint.setKey(string);
} // More of the same.
} else if (constraint instanceof PConstraint) {
// As the above if() group.
} // etc.
這個設計有比抽象函數更好的解決方案嗎?
使用這個原則
在接口中編程,並封裝在抽象類或接口中不斷變化的行為。
例如:對於上面給出的例子
接口 - 約束
抽象類 - FConstraint
具體類 - PConstraint,TConstraint,UConstraint,AConstraint
您的問題沒有足夠的信息來說明您在每種情況下需要做的實際工作,但通常是這樣的代碼:
Object constraint = item.getConstraint();
if (constraint instanceof AConstraint) {
// Work
} else if (constraint instanceof PConstraint) {
// Work
} // etc.
是一種強烈的氣味,使用多態和重構成這樣的東西:
Constraint constraint = item.getConstraint();
constraint.doWork(...);
特定類看起來像這樣:
public class AConstraint {
public ... doWork(...) {
if (getValue() == null) {
setValue(string);
} else if (getKey() == null) {
setKey(string);
} // More of the same.
}
}
你可以這樣做:
public interface Constraint{}
public abstract class VariableConstraint implements Constraint
{
/* hold 3 shared variables here */
}
public class UConstraint extends VariableConstraint{}
public class PConstraint extends VariableConstraint{}
public class AConstraint extends VariableConstraint{}
public abstract class EmptyConstraint implements Constraint {}
public class TConstraint extends EmptyConstraint {}
在Constraint
指定常用功能:您希望能夠對Constraint
對象執行的任何操作(實際上可能是其中一個子類型的對象),您在子類中重寫的Constraint
中具有該功能的方法。
對於那些功能沒有意義的父類,你可以有簡單的(例如空的)實現。
這樣您就不需要關心對象的具體類,只需使用超類提供的工具即可
將Constraint
作為接口。 定義一個擴展此Constraint
的抽象類,它應該具有共享變量。 UConstraint
, AConstraint
應該擴展這個具有共享變量的抽象類。 其余類可以直接實現Constraint
接口。 代碼實例應該改變
Constraint constraint = item.getConstraint();
constraint.doWork(..);
總是更好的設計是針對接口編寫代碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.