Decoratorパターン
私は実際によく文書Decoratorパターンを使用してArrayList
を包むお勧めします。
public class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{
private final List<MyBusinessObject> target;
public ValidatingListDecorator(List<MyBusinessObject> target) {
this.target = target;
}
@Override
public MyBusinessObject set(int index, MyBusinessObject element)
{
validate(element);
return target.set(index, element);
}
@Override
public boolean add(MyBusinessObject o)
{
validate(o);
return target.add(o);
}
//few more to implement
}
利点:
- したい場合は、まだ検証せずに生のリストにアクセスすることができます(ただし、あなたができるあなたは、単にデリゲートがメソッドのほとんどが、検証ロジックを追加することを別の
List
の実装を使用してArrayList
を包みますこれを制限する)
- 異なるバリデーションを積み重ねることが容易になるように、それらを選択的にオン/オフします。
- @helios
- で述べたようにcomposition over inheritanceを促進するテスト容易性
- が特定
List
実装にあなたを結ぶません、あなたはLinkedList
またはHibernate永続的なリストを-backedに検証を追加することができます向上させます。すべてのコレクションを検証するために、汎用のCollection
デコレータについて考えることもできます。
実装は実装にもかかわらず
ノートオーバーライドしながら、あなたがについて覚えている方法のかなり多くがあります覚えている:(?)subList()
、add()
、addAll()
、set()
を、など
また、あなたのオブジェクトは不変でなければならず、さもなければ、ユーザは有効なオブジェクトを追加/設定し、後でそれを変更して契約に違反することができる。
グッドOO設計
Finaly私が書いた:
validate(element)
しかし考えてみます。
element.validate()
をより良いデザインです。
スタッキング検証あなたは、単一の、別のクラスに各proprty/apsectを検証し、検証をスタックしたい場合は、以下のイディオムを検討する前に述べたように
:
public abstract class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{
private final List<MyBusinessObject> target;
public ValidatingListDecorator(List<MyBusinessObject> target) {
this.target = target;
}
@Override
public MyBusinessObject set(int index, MyBusinessObject element)
{
validate(element);
return target.set(index, element);
}
protected abstract void validate(MyBusinessObject element);
}
を...といくつかの実装:
class FooValidatingDecorator extends ValidatingListDecorator {
public FooValidatingDecorator(List<MyBusinessObject> target)
{
super(target);
}
@Override
protected void validate(MyBusinessObject element)
{
//throw if "foo" not met
}
}
class BarValidatingDecorator extends ValidatingListDecorator {
public BarValidatingDecorator(List<MyBusinessObject> target)
{
super(target);
}
@Override
protected void validate(MyBusinessObject element)
{
//throw if "bar" not met
}
}
のみFOOを検証したいですか?
List<MyBusinessObject> list = new FooValidatingDecorator(rawArrayList);
は両方FOOとバーを検証したいですか?別の戦略に切り替えることはできません、例えば - 私はあなたと同意するが、IMO 1つのトレードオフの特定のリストの実装から延びるあり
List<MyBusinessObject> list =
new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList));
+1の継承を超える構成! – helios
+1詳細な返信をありがとう – Sudhakar