2016-03-30 7 views
4

私は、データセットを管理するために使用される6つのメソッドを持つインターフェイスを持っています。実装間で異なる唯一の方法はgetSerializedVersion()であり、シリアライズ文字列を解析できるコンストラクタです。実装が単一のメソッドでのみ異なる場合は、どのデザインパターンをお勧めしますか?

public interface DataSets { 
    public void addEntry(...); 
    public void removeEntry(...); 
    public void manipulateEntry(...); 
    public SomeType getEntry(...); 
    public List<SomeType> getAllEntries(); 
    // This differs: 
    public String getSerializedVersion() 
} 

私はインターフェースを変更できません。

私の最初のアイデアは、抽象クラスを生成し、最初の5つのメソッドを実装することでした。具体的な実装(例:DataSetsXMLDataSetsYAML、...)は、getSerializedVersion()とその文字列を読み込んでオブジェクトを初期化できるコンストラクタを実装するだけです。

別のデザインをテストすると、より良い(https://stackoverflow.com/a/7569581)かもしれませんが、どちらが良いでしょうか?

回答は主観的かもしれないが、私は別のアプローチのいくつかの一般的な規則または少なくとも(目的)長所と短所があると思い、...

+4

getSerializedVersion()を実装するために、単一のクラスを使用し、シリアライザに委譲し、コンストラクタに引数として渡すことができます。シリアライザ(YamlSerializer、XmlSerializerなど)のN個の実装を持っています –

+0

@ JBNizetの答えが行く方法です。クラスの責任の観点から、シリアライズはデータセットを管理する以外の仕事のようです。抽象クラスを使用する必要はなく、この設計ミスをさらにエンコードする必要はありません。 – Cardano

+0

@JBNizet:あなたのコメントから答えを書くことはできますか? – Edward

答えて

9

あなたが説明しているのは、クラスの動作に関係なく、シリアル化されてシリアル化されていないことです。つまり、DataSetsXMLDataSetsYAMLは同じ機能を持ちますが、異なるフォーマットにシリアライズされます。

これは、getSerializedVersion()DataSetsクラスと結合して維持する利点がないことを意味します。あなたはそれらを完全に切り離すべきです。例えば、

interface DataSetsSerializer 
{ 
    public DataSets unserialize(String string); 
    public String serialize(DataSets sets); 
} 

、その後、ちょうどこのクラスでdifferente実装の世話をする:

あなたはの直列化インタフェースの並べ替えを持っている可能性が

class YAMLDataSetsSerializer implements DataSetsSerializer 
{ 
    public DataSets unserialize(String string) { 
    DataSets sets = new DataSets(); 
    ... 
    } 

    public String serialize(DataSets sets) { 
    ... 
    } 
} 

をJB Nizetコメントに工夫することで、あなたの場合DataSetsSerializerDataSetsインスタンス内に保たなければなりません(特定の直列化方法が直列化されるべきデータに束縛されないように、IMHOはどのような場合でもデカップリングする必要があるため意味がありません)。この場合、提案されたインターフェイスにわずかな変更が必要です。これは巧妙なデザインではなく、要件を尊重します。

+0

彼はインタフェースを変更できないので、 'getSerializedVersion'が呼び出されたときに、これらのシリアライザの使用に関するメッセージとともに' UnsupportedOperationException'をスローする必要があることを付け加えます。 –

+0

私はシリアル化のデカップリングに同意します。しかし、APIユーザーは2つの参照を保持する必要があります.1つは「DataSets」、もう1つはシリアル化です。 (私が間違っている場合は私を修正してください)。私はそれが理由として定義されている理由だと思う。だからおそらく 'JB Nizet'のコメント(デリゲートからシリアライザへのコンストラクタの追加)の解決策が、私の場合に入る方法です。それとも、そのアプローチの不利な点がありますか? – Edward

+0

あなたの答えに 'JB Nizet'のコメントを話したら、私はそれを受け入れることができるでしょう。 – Edward

1

は、私は抽象クラスを使用するのが妥当だと思います。抽象クラス(抽象クラ​​スも間接的にテストする)の具体的な実装をテストできます。