2012-05-01 5 views
3

私は、共通の機能を共有する多数のクラスを持つシステムを構築していますが、クラスのサブセットの重複によって共有される機能の量は少なくて済みます。これを実装する最良の方法は何ですか?スパース共通機能を持つサブクラスの実装

例として化学のような他の分野の例がありますが、私はSVG(私は化学のサブセットを実装しています)を取ります。これと関連する問題には、明確で不変なXMLスキーマの設計仕様があります。

多くの共通機能を持つ基本クラスSVGElementがあります。他のすべてのクラス(SVGLineSVGCircle ...)は、これから直接派生しています。次に、(XML属性によって)仕様に定義されている他の機能があります。

- x 
- width 
- fill 
- opacity 

などです。新しい要素や属性を再作成することはできません。例えば、SVGはcircleellipse(古典的な問題)の両方を持ち、1つはr(adius)、もう1つはwidthheightです。サブクラスが共通の機能を共有する場合、共通のコードを使用できます。

は、次の解決策があるように思える:

  • は、各サブクラス内の各機能を実装します。 (エラーが発生し退屈な)
  • スーパークラス(SVGElement)内のすべての関数を実装し、派生したメソッドno-opsを作成します。
  • インターフェイスを作成し(hasWidth)、各(WidthImplementor)のデリゲートサブクラスを作成します。各クラスには、インターフェースリスト(各SVGアトリビュートごとに最大20個)があり、そのような実装者は100〜200人かもしれません。
  • スキーマのコードを自動生成します。私はこれを試して、それはclunkily動作が、私はかなりの実装を持っていない。ほとんどのXML-to-Javaシステムはライブラリシステムの構築には適していないので、私はこれを自分で大量に行う必要がありますので注意してください。

などがあります。

私は、抽象を設計する方法に関する他の問題があることを認識していますが、ここではほとんど修正されています。私は一般的な解決策を望んでいます。SVGだけでなく、わかりやすい例として使われています。たとえば、CML(Chemical Markup Language)には、100〜200個のサブクラスと100〜200個の属性が散在しています。

+0

を設計は=>あなたはSVGの仕様を変更することはできません与えられています。しかし、あなたはクラス定義/クラス数を変更できますか? – ArjunShankar

+0

本当にありません。デザインは '' => 'SVGCircle.java'です。 'SVGHasXHasFill.java'などの範囲はほとんどありません。また、人間や機械にとってはかなり自動でなければなりません。 –

+0

これらのクラスは実際には何らかの振る舞いをしていますか(つまり、適切なオブジェクトですか?)または、SVGの定義にマップされたプロパティのバッグですか? – artbristol

答えて

2

'一般的な'機能を実装することを検討したいかもしれません 'Decorators'。 SVG要素を解析する際に、これらのデコレータを実行時に適用することができます。あなたが楕円見たときに

abstract class SVGElement { 

    public void draw (void) { 
     return; 
    } 

    public boolean hasWidth (void) { 
     return false; 
    } 

    public boolean hasHeight (void) { 
     return false; 
    } 

    // .. 
} 

// An abstract decorator 
abstract class SVGElementDecorator extends SVGElement { 

    protected SVGElement decoratedElement; 

    public SVGElementDecorator (SVGElement decoratedElement) { 
     this.decoratedElement = decoratedElement; 
    } 

    public void draw (void) { 
     decoratedElement.draw(); 
    } 
} 

// Decorator to add width functionality 
class WidthDecorator extends SVGElementDecorator { 

    private double width; 

    public WidthAndHeightDecorator (SVGElement decoratedElement) { 
     super(decoratedElement); 
    } 

    // override base class implementation 
    public boolean hasWidth (void) { 
     return true; 
    } 

    // implement a new method 
    public double getWidth (void) { 
     return width; 
    } 

    public void draw (void) { 

     // do special stuff for width 
     // .. 

     // then draw the rest 
     decoratedElement.draw(); 
    } 
} 

次に、:

SVGElement ellipse = new SVGElement(); 
ellipse = new WidthDecorator (ellipse); 
ellipse = new HeightDecorator (ellipse); 
+0

これは私が探しているものです。私はデコレータパターンを使用していない、これはいくつかの読書を行うための説得力のある議論です! –

+0

@ peter.murray.rust - あなたは*有名なGoFの本:http://en.wikipedia.org/wiki/Design_Patternsについて聞いたことがあります。私は長い間、未読のままで横たわっているコピーを持っています:( – ArjunShankar

+0

私は実際にGoFについて聞きましたが、パターンに関する他の本を持っていますが、私はいつどのパターンを使うべきかを認識していません! –

関連する問題