JAVA PECS法則
PECSとは?PECSとは「Producer Extends,Consumer Super」のこと.言い換えれば、パラメトリックタイプが生産者を表す場合、;消費者を表す場合は.
以下は簡単なStackのAPIインタフェースです.
一連の要素を順番にStackに入れる方法を追加したいと仮定すると、次のような実現方法が考えられます.
Stackがあると仮定し,Integer,LongなどのNumberのサブタイプの集合を柔軟に処理したい.
この場合、コードコンパイルはパスできません.タイプNumberとIntegerでは、後者はNumberのサブクラスですが、任意のNumberセット(List)に対してIntegerセット(List)のスーパークラスではありません.汎用型は可変ではないためです.
幸いjavaは有限ワイルドカードというパラメータ化タイプを提供しており、pushAllパラメータは「EのサブタイプのIterableインタフェース」に置き換えられています.
これで正しくコンパイルできますが、ここのとは、いわゆるproducer-extendsである.ここのIterableは生産者ですが、.だってIterableは、任意のEのサブクラスを収容することができる.操作を実行すると、反復可能なオブジェクトの各要素はEとして操作できます.
これに対応して、Stackコレクションから各要素をポップアップし、指定したコレクションに追加するメソッドpopAll()メソッドがあると仮定します.
StackオブジェクトとCollection
以下は簡単なStackのAPIインタフェースです.
- public class Stack<E>{
- public Stack();
- public void push(E e):
- public E pop();
- public boolean isEmpty();
- }
一連の要素を順番にStackに入れる方法を追加したいと仮定すると、次のような実現方法が考えられます.
- public void pushAll(Iterable<E> src){
- for(E e : src)
- push(e)
- }
Stack
- Stack<Number> numberStack = new Stack<Number>();
- Iterable<Integer> integers = ....;
- numberStack.pushAll(integers);
この場合、コードコンパイルはパスできません.タイプNumberとIntegerでは、後者はNumberのサブクラスですが、任意のNumberセット(List
幸いjavaは有限ワイルドカードというパラメータ化タイプを提供しており、pushAllパラメータは「EのサブタイプのIterableインタフェース」に置き換えられています.
- public void pushAll(Iterable<? extends E> src){
- for (E e: src)
- push(e);
- }
これで正しくコンパイルできますが、ここのとは、いわゆるproducer-extendsである.ここのIterableは生産者ですが、.だってIterableは、任意のEのサブクラスを収容することができる.操作を実行すると、反復可能なオブジェクトの各要素はEとして操作できます.
これに対応して、Stackコレクションから各要素をポップアップし、指定したコレクションに追加するメソッドpopAll()メソッドがあると仮定します.
- public void popAll(Collection<E> dst){
- if(!isEmpty())
- dst.add(pop());
- }
Stack