0

「Operation」という抽象クラスがあり、このクラスには「Prepare」という抽象メソッドがあります。

public abstract class Operation {
    public abstract void prepare() throws Exception;
    public abstract void run() throws Exception;
    // other stuff here that's not abstract
    public void printHelloWorld() { 
         System.out.println("Hello World!");
    }

}

唯一の問題は、 「操作」( Operation を拡張する一部のクラス) であるいくつかのものは、準備するために引数が必要であることです (一部は int が必要で、一部は String が必要で、一部はより複雑なデータ型が必要です..したがって、常に int であるとは限りません)。

public class Teleportation extends Operation {
   @Override
   public void prepare(int capacityRequired ) throws Exception {
        // do stuff
   }
   @Override
   public void run() throws Exception {
   }
}

これを達成するためにどの OOP パターンを使用し、このコードをどのように設定すればよいですか?

編集 :

理想的には、次のような操作を準備して実行したいと考えています。

for (Operation operation : operations ) {
  operation.prepare();
  operation.run(); 
}

このソリューションを使用すると仮定します:

 public class Teleportation extends Operation {
       private int cReq;
       public void setCapacityRequired(int cReq) {
         this.cReq = cReq;
       }
       @Override
       public void prepare() throws Exception {
                // I can do the preparation stuff
                // since I have access to cReq here
       }
       @Override
       public void run() throws Exception {
       }
    }

次に-これを回避できるかどうか疑問に思います:

 for (Operation operation : operations ) {
      if (operation.getClass().isInstanceOf(Teleporation.class)) {
               ((Teleporation)operation).setCapacityRequired( 5 );
      }
      operation.prepare();
      operation.run(); 
    }
4

4 に答える 4

2

実装に必要なデータを追加し、それをクラス実装のフィールドに格納できるコンストラクタを追加することをお勧めします。

あなたの例:

public class Teleportation extends Operation {
    private final int capacityRequired;
    public Teleportation(int capacityRequired) {
        this.capacityRequired = capacityRequired;
    }
    public void prepare() throws Exception {
    // do stuff using the capacityRequired field...
    }
}

このアプローチは、より複雑なパラメーターにも適用されます。

于 2013-10-10T15:18:38.327 に答える
2

ここで最初に行うことは、抽象クラス操作をオーバーライドし、容量をオーバーロードすることです。

public class Teleportation extends Operation {

    public void prepare() throws Exception {
        prepare(0);
    }

    public void prepare(int capacityRequired) throws Exception {
        //do stuff
    }
}

また、 KISSステートメントとYAGNIステートメントを思い出してください。コードのどこにでもデザイン パターンを使用する必要はありません。デザイン パターンを使用すると、物事が単純になります。

于 2013-10-10T15:17:33.440 に答える
2

抽象クラスを拡張して 2 つのメソッド シグネチャを含めるか、シグネチャを変更して varargs int パラメータを受け取る必要があります。

public abstract class Operation {
    public abstract void prepare(int... args) throws Exception;
}
于 2013-10-10T15:17:48.163 に答える
1

操作クラスにジェネリック クラスを使用できます。

public abstract class Operation<T>
{
    private T operationModel;

    public Operation(T operationModel)
    {
        super();
        this.operationModel = operationModel;
    }

    public abstract void prepare() throws Exception;

    public abstract void run() throws Exception;

    public T getOperationModel()
    {
        return operationModel;
    }
}

次に、具象クラスの場合は、適切なパラメーター型で拡張します (操作ごとに特定のクラスを使用できます)。

public class TeleOperation extends Operation<TeleOperationModel>
{
    public TeleOperation(TeleOperationModel operationModel)
    {
        super(operationModel);
    }

    @Override
    public void prepare() throws Exception
    {
        TeleOperationModel teleOperationModel = getOperationModel();
        //...

    }

    @Override
    public void run() throws Exception
    {

    }
}

public class TeleOperationModel
{
    private int capacity;
    ....
}

と:

public class MicroOperation extends Operation<MicroOperationModel>
{
    public MicroOperation(MicroOperationModel operationModel)
    {
        super(operationModel);
    }

    @Override
    public void prepare() throws Exception
    {
        MicroOperationModel  microOperationModel = getOperationModel();
        //...
    }

    @Override
    public void run() throws Exception
    {

    }
}

public class MicroOperationModel
{
    private int x;
    private int y;
    private int z;
    ....
}
于 2013-10-10T16:00:17.870 に答える