1

現在発生している設計上の問題があります。

コンポーネントの階層があるとしましょう。これらの各コンポーネントは、次のComponentような抽象型から派生します。

public abstract class Component
{
    public abstract Component Parent { get; }
    public abstract ComponentCollection Children { get; }
}

ここで、これらのコンポーネントにいくつかのオプション機能を追加したいと思います。例として、コンポーネント階層内で検索し、階層内でコンポーネントを選択できるようにしましょう。

次のような基本クラスでこれらのオプション機能を提供することは悪い習慣と見なされますか?

public abstract class Component
{
    // Other members

    public abstract bool IsSearchable { get; }
    public abstract bool Search(string searchTerm);

    public abstract bool IsSelectable { get; }
    public abstract bool Select();
}

「検索機能」と「選択機能」は、たとえば戦略パターンを使用して派生コンポーネントで管理されますか?

どういうわけか、これは SRP に違反しているように思えますが、私の意見では、唯一の代替手段は、各オプション機能のインターフェイスを持ち、この機能をサポートするコンポーネントにのみ実装することです。

私の意見では、これには、コンポーネントが特定の機能を提供するかどうかを確認するたびに、このようなコードを書かなければならないという欠点があります。

public bool Search(Component component, string searchTerm)
{
    ISearchable searchable = component as ISearchable;
    if(searchable != null)
    {
        searchable.Search(searchTerm);
    }
}

どちらの戦略を選択しますか、またはより良いアイデアがありますか?

前もって感謝します!

4

3 に答える 3

1

可能なオプション:

あなたが言うように、検索可能性/選択可能性の実装が戦略パターン (依存性注入) によって提供される場合、ISearchable と ISelectable のインターフェイスはより良いアイデアだと思います。

これらのインターフェースから戦略オブジェクトを派生させ、基本コンポーネント クラス (GetSearchable()、GetSelectable()) でそれらのゲッターを実装できます。ここで、Component のデフォルトの実装は null を返します (または、インターフェースの no-op 実装を返す場合)。 nullが嫌いです)。

于 2011-06-15T09:29:02.653 に答える
0

なぜデコレータを使わないのですか?

Component c = new Component ();
var selectableAndSearchableOne = new SelectableComponent (new SearchableComponent (c));
于 2011-06-16T21:36:47.780 に答える
0

もう 1 つわかりました。今回は、コンポーネントの拡張ポイントもわかっています。来客パターンで

public interface IHasExtensions
    {
        List<Extension> Extensions { get; }
        void Extend (Extension ext);
    }

    public class Component : IHasExtensions
    {
        List<Extension> exts = new List<Extension> ();

        public List<Extension> Extensions
        {
            get { return exts; }
        }

        public void Extend (Extension ext)
        {
            exts.Add (ext);
        }

        void Draw() { }
    }

    public abstract class Extension
    {
        readonly protected Component _Component;

        public Extension(Component component)
        {
            _Component = component;
        }
    }

    public class SearchExtension : Extension
    {
        public SearchExtension (Component component) : base (component)
        {

        }
    }

    public class SelectionExtension : Extension
    {
        public SelectionExtension (Component component) : base (component)
        {

        }
    }

    public class test_fly
    {
        void start ()
        {
            Component c = new Component ();
            c.Extend (new SearchExtension (c));
            c.Extend (new SelectionExtension (c));

            var exts = c.Extensions; // I Know the extensions now
        }
    }
于 2011-06-18T22:30:08.883 に答える