1

今日も同様の質問をしましたが、要件が変更されたと言われました。

(PO) と(POL)Productの3 つのクラスがあります。製品には PO が含まれ、PO には POL が含まれます。これらのクラスはすべて、CMS と呼ばれる抽象クラスを拡張します。ProductOfferingProductOfferingLists

PO を P に、POL を PO に付けたいのですが、クラス名を除いてロジックが同じであるため、再利用可能なメソッドを探しています。

残念ながら、私のテスター クラスには 2 つのメソッドが必要であり、階層クラスには抽象 CMS コントラクトを満たすためにキャストが必要です。

これは私を夢中にさせています。複数のメソッドとキャストを使用しないように、これをより再利用可能にするにはどうすればよいですか?

package puzzler;
import java.util.ArrayList;
import java.util.List;

public class Tester {
    public static void main(String[] args) {
        Product p = new Product();
        PO pa = new PO();
        POL po = new POL();

        List<PO> lpa = new ArrayList<PO>();
        List<POL> lpo = new ArrayList<POL>();

        attachChildToParent(lpa, p);
        attachChildToParent(lpo, pa);
    }

    static void attachChildToParent(List<PO> listChild, Product parent) {
        for (PO po : listChild) {
            parent.attach(po);
        }
    }

    static void attachChildToParent(List<POL> listChild, PO parent) {
        for (POL po : listChild) {
            parent.attach(po);
        }
    }
}

CMS クラス:

package puzzler;

abstract class CMS {
    abstract void attach(CMS childNode);
}

製品クラス - PO を所有する階層の最上位:

package puzzler;
import java.util.List;

public class Product extends CMS {
    List<PO> lpo;

    public List<PO> getLpo() {
        return lpo;
    }

    public void setLpo(List<PO> lpo) {
        this.lpo = lpo;
    }

    @Override
    void attach(CMS childNode) {
        this.getLpo().add((PO)childNode);
    }
}

製品によって所有され、製品提供リストを所有する製品提供

package puzzler;
import java.util.List;

public class PO extends CMS {
    List<POL> lpol;

    public List<POL> getLpo() {
        return lpol;
    }

    public void setLpo(List<POL> lpol) {
        this.lpol = lpol;
    }


    @Override
    void attach(CMS childNode) {
        this.getLpo().add((POL)childNode);
    }
}    

PO が所有する製品提供リスト (POL)

package puzzler;

public class POL extends CMS {
    @Override
    void attach(CMS childNode) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
4

3 に答える 3

1

(Java 7 構文が使用されていますが、Java 6 に簡単に適応できます)

CMS クラスを次のように定義します。

public abstract class CMS<C extends CMS<?>> {
    public abstract void attach(C childNode);
}

次に、 Product クラスは次のようになります。

public class Product extends CMS<PO> {
    private List<PO> lpo = new ArrayList<>();

    public List<PO> getLpo() {
        return lpo;
    }

    public void setLpo(List<PO> lpo) {
        this.lpo = lpo;
    }

    @Override
    public void attach(PO childNode) {
        getLpo().add(childNode);
    }
}

次に、PO クラスは次のようになります。

public class PO extends CMS<POL> {
    private List<POL> lpol = new ArrayList<>();

    public List<POL> getLpo() {
        return lpol;
    }

    public void setLpo(List<POL> lpol) {
        this.lpol = lpol;
    }

    @Override
    public void attach(POL childNode) {
        getLpo().add(childNode);

    }
}

次に、POL クラスは次のようになります。

public class POL extends CMS<CMS<?>> {
    @Override
    public void attach(CMS<?> child) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

最後に、 Tester クラスは次のようになります。

public class Tester {
      public static void main(String[] args) {
            Product p = new Product();
            PO po = new PO();

            List<PO> pos = new ArrayList<PO>();
            List<POL> pols = new ArrayList<POL>();

            attachChildToParent(pos, p);
            attachChildToParent(pols, po);
        }

    private static <C extends CMS<?>> void attachChildToParent(List<C> childNodes, CMS<C> parent) {
        for (C childNode : childNodes) {
            parent.attach(childNode);
        }
    }
}

必要なメソッドは 1 つだけで、キャストは不要です。

于 2012-08-17T14:51:24.780 に答える
0

どこでも使用する必要がある実装クラスで使用するインターフェースのような抽象クラス。

追加のキャストを削除し、2 つのメソッドを 1 つに置き換えました。

import java.util.ArrayList;
import java.util.List;

public class Tester {
  public static void main(String[] args) {
    Product p = new Product();
    PO pa = new PO();
    POL po = new POL();

    List<CMS> lpa = new ArrayList<CMS>();
    List<CMS> lpo = new ArrayList<CMS>();

    attachChildToParent(lpa, p);
    attachChildToParent(lpo, pa);
  }

  static void attachChildToParent(List<CMS> listChild, CMS parent) {
    for (CMS po : listChild) {
      parent.attach(po);
    }
  }
}

abstract class CMS {
  abstract void attach(CMS childNode);
}

class Product extends CMS {
  List<CMS> lpo;

  public List<CMS> getLpo() {
    return lpo;
  }

  public void setLpo(List<CMS> lpo) {
    this.lpo = lpo;
  }

  @Override
  void attach(CMS childNode) {
    this.getLpo().add(childNode);
  }
}

class PO extends CMS {
  List<CMS> lpol;

  public List<CMS> getLpo() {
    return lpol;
  }

  public void setLpo(List<CMS> lpol) {
    this.lpol = lpol;
  }


  @Override
  void attach(CMS childNode) {
    this.getLpo().add(childNode);
  }
}
class POL extends CMS {
  @Override
  void attach(CMS childNode) {
    throw new UnsupportedOperationException("Not supported yet.");
  }
}
于 2012-08-17T15:27:49.370 に答える
0

コンポジションパターンでジェネリックを使用するだけです。

  • CMS をインターフェイスとして定義する
  • タイプによってパラメーター化された単一のクラス PO を定義する
  • CMSImplなどでメソッドを1回実装する

http://en.wikipedia.org/wiki/Generics_in_Java

http://en.wikipedia.org/wiki/Composite_pattern

于 2012-08-17T14:21:55.687 に答える