Что такое хороший способ иметь дело с несколькими типами объектов в одной форме? - PullRequest
1 голос
/ 20 января 2012

У меня есть абстрактный базовый класс и два производных класса.Базовый класс содержит 6 свойств, все из которых могут поддерживаться в форме.

Два классифицированных производных имеют одно дополнительное свойство.Эти два свойства также могут поддерживаться в одной и той же форме.

В моей форме теперь есть такой код:

  btnSomething.visible = (myObject is DerivedA);
  pnlPanel.visible = !(myObject is DerivedA);

  if(myObject is DerivedA)
    myBindingSource.DataSource = myObject as DerivedA

  mySecondBindingSource = myObject;

Я не очень доволен этим подходом, он пахнет.Так что мой вопрос в том, что является хорошим / хорошим способом сделать это более оригинальным?Потому что, возможно, в будущем появится DerivedC ...

Я думаю, что этот подход нарушает принцип OCP (и, возможно, другие принципы)

Ответы [ 3 ]

2 голосов
/ 20 января 2012

Вы можете использовать полиморфизм и наследование здесь:

Определить интерфейс

interface ICommonFeatures
{
    bool ContainsFoo {get;}
    //yak-yak
}

Тогда ваши производные классы реализуют его

class DerivedA: ICommonFeatures
{
    bool ContainsFoo {get {return true;}}
    //so-and-so
}
class DerivedB: ICommonFeatures
{
    bool ContainsFoo {get {return false;}}
    //this-and-that
}

И когда вы его используете,Вы имеете дело только с интерфейсом

ICommonFeatures foo = new DerivedB();

btnSomething.visible = foo.ContainsFoo;
pnlPanel.visible = foo.Prop2;
myBindingSource.DataSource = foo.CurrentDataSource
0 голосов
/ 20 января 2012

Я бы объявил абстрактный логический метод / свойство для каждого элемента управления, который должен вести себя в соответствии с базовым типом.

Например

// to handle pnlPanel.visible = !(myObject is DerivedA);    
abstract bool SupportsPanel{get;}

Что касается ваших источников привязки, я бы также предоставил некоторые виртуальные свойства BindingSource и SecondBindingSource.

Может быть, что-то вроде (чисто пример)

public abstract class BaseClass
{
    // All your exising class declaration here

    public virtual object BindingSource
    {
        get
        {
            // By default, a BaseClass is not valid as a binding source
            return null;
        }
    }

    public virtual object SecondBindingSource
    {
        get
        {
            // By default, a BaseClass is a valid Second Binding source
            return this;
        }
    }
}

public class DerivedA : BaseClass
{
    // All your exising class implementation here

    public override object BindingSource
    {
        get
        {
            // For DerivedA, the data sourse is itself.
            // other classes might have their own implementations.
            return this;
        }
    }

    // No need to override SecondBindingSource as the BaseClass one works as expected.

}

Итак, ваш код может перестать заботиться о типе объекта и выглядеть следующим образом:

myBindingSource.DataSource = myObject.BindingSource;
mySecondBindingSource = myObject.SecondBindingSource;

Надеюсь, это поможет.

0 голосов
/ 20 января 2012

Сумасшедшая идея - сделать интерфейс расширяемым.Вы можете сделать так, чтобы форма реализовывала базовую форму.

Тогда в производный класс формы вы вставляете только недостающие элементы управления и поведение для его класса модели.В классе или библиотеке производной модели у вас может быть какая-то привязка к правильной форме.

Хороший подход для этого будет следовать некоторым принципам MVP.

Надеюсь, это поможет вам как-то ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...