簡體   English   中英

如何整合多個類並避免使用instanceof?

[英]How to Consolidate Many Classes and Avoid instanceof?

我正在幫助開發的程序應該輸出幾個動態生成的問題供用戶回答。 問題具有不同的類型,並且具有相應的類Constraint ,它們用用戶給定的信息填充。 我的問題是如何為不同的約束創建統一的行為。

                    ---->Constraint<--------------------
                    |                  |               |
                  FConstraint        PConstraint    TConstraint
                  |         |
            UConstraint AConstraint

基類Constraint為空,TConstraint也是如此。

UConstraintPConstraintAConstraint共享三個變量。 但是, UConstraintAConstraint還有一個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的抽象類,它應該具有共享變量。 UConstraintAConstraint應該擴展這個具有共享變量的抽象類。 其余類可以直接實現Constraint接口。 代碼實例應該改變

Constraint constraint = item.getConstraint();
constraint.doWork(..);

總是更好的設計是針對接口編寫代碼

暫無
暫無

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

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