Использование MVP для составной модели структурированных объектов - PullRequest
0 голосов
/ 31 августа 2009

(отредактировано много) У меня есть несколько классов с участниками рефератов. Конкретный тип абстрактных членов должен быть определен в экземпляре класса на основе пользовательского ввода. Однако конкретный тип второго члена может зависеть от первого.

Я пытаюсь сделать что-то, помня шаблон проектирования MVP. Я учил тому, как заставить докладчика передать делегата в Ctor модели, который он (Ctor) будет использовать для запроса информации, необходимой для создания экземпляра класса. Я не уверен, что это хорошая идея. Вот что я написал:

// In the Model :
public class Model
{
    public E Element1;
    public E Element2;

    public Model(CustomCtor<ModelElement, IModelElement> GetModelElement)
    {
        this.Element1 = (E)GetModelElement(ModelElement.E, null);
        this.Element2 = (E)GetModelElement(ModelElement.E, null);
        //Element2 does not depend on Element1 in this case though.
    }
}

public abstract class E : IModelElement { }

public class EA : E
{
    public string Element1;
    public EA(string Element1) { this.Element1 = Element1; }
}

public class EB : E
{
    public int Element1;
    public EB(int Element1) { this.Element1 = Element1; }
}

public interface IModelElement { }

public enum ModelElement { E, EA, EB }

// In the Presenter :
public class Presenter
{
    View.View view1;

    public Presenter() { }
    public void SetView(View.View view) { this.view1 = view; }

    public Model.Model MakeModel()
    {
        CustomCtor<ModelElement, IModelElement> GetModelElement = new CustomCtor<ModelElement, IModelElement>(GetModelElement<ModelElement, IModelElement>);
        return new Model.Model(GetModelElement);
    }

    private Model.IModelElement GetModelElement<ModelElement, Tout>(Model.ModelElement ME, object obj)
    {
        switch (ME)
        {
            case Model.ModelElement.E:
                return MakeE();
            // One case per Model.ModelElement
            default:
                throw new Exception("ModelElement not implemented in the Presenter.");
        }
        return default(Model.IModelElement);
    }

    private E MakeE()
    {
        switch (view1.AskEType())
        {
            case 1:
                return MakeEA();
            case 2:
                return MakeEB();
            default:
                throw new Exception();
        }
    }

    private EA MakeEA() { return new EA(view1.AskString("EA.Element1 (String)")); }
    private EB MakeEB() { return new EB(view1.AskInt("EB.Element1 (Int)")); }
}

// Shared to the Model and the Presenter :
public delegate TOut CustomCtor<EnumType, TOut>(EnumType Enum, object Params) where EnumType : struct;

// In the View :
public class View
{
    public int AskEType()
    {
        Console.WriteLine(string.Format("Type of E : EA(1) or EB(2)?"));
        return int.Parse(Console.ReadLine());
    }
    public string AskString(string Name)
    {
        Console.Write(string.Format("{0} ? ", Name));
        return Console.ReadLine();
    }
    public int AskInt(string Name)
    {
        Console.Write(string.Format("{0} ? ", Name));
        return int.Parse(Console.ReadLine());
    }
}

//In the Program :
class Program
{
    static void Main(string[] args)
    {
        View.View view1 = new View.View();
        Presenter.Presenter presenter1 = new Presenter.Presenter();

        presenter1.SetView(view1);
        presenter1.MakeModel();
    }
}

Это имеет смысл? Есть ли название для того, что я пытаюсь сделать? (рядом с "Странной вещью") Вы знаете шаблон дизайна, на котором я должен читать? Я учил смешивать шаблон проектирования Builder с MVP, но я не уверен, как мне это сделать.

Спасибо

1 Ответ

1 голос
/ 31 августа 2009

Я не уверен, что это то, о чем вы спрашиваете, но я предполагаю, что вы пытаетесь сохранить свой взгляд изолированным от вашей модели. Если это действительно то, что вы пытаетесь сделать, я думаю, что вы используете слишком сложный подход. Представление - просто средство представления и обратной связи. Ему действительно не нужно ничего знать о моделях, он может быть спроектирован так, чтобы использовать простые данные в какой-то сумке свойств. Это создает более чистое разделение, однако, это часто делает рендеринг данных и поддержание представления намного сложнее.

Первый вопрос, который я хотел бы задать, ДЕЙСТВИТЕЛЬНО ли стоит того, чтобы тратить столько усилий на то, чтобы ваш взгляд был полностью изолирован от вашей модели? Что вы действительно получаете, имея абсолютное разделение?

Если вам действительно нужно разделение, убедитесь, что вы понимаете роли представления и докладчика. Взгляд тупой ... он ничего не знает и ничего не делает. Он представляет информацию и формы. Браузер выдает команды, запрошенные пользователем. Презентатор обрабатывает команды и направляет данные в его представление. Понятие «ведущий, спрашивающий мнение», как правило, неверно. Докладчик должен обрабатывать команду (запрос http) напрямую, поэтому он должен знать все подробности о конкретной команде. Когда приходит время визуализации представления, докладчик должен предоставлять любые данные представлению в любой форме, в которой оно требуется. Если вы не хотите, чтобы ваше представление знало о вашей объектной модели, либо создайте свойства в представлении. сам, чтобы содержать данные, или создать специфичную для представления модель, которая инкапсулирует требуемые данные.

EDIT:

Я только что прочитал ваше обновление. Я думаю, что теперь я понимаю вашу проблему немного лучше. Прежде всего, прежде чем я пойду дальше, вам нужно немного реорганизовать обязанности. В настоящее время у вас это так, что ваше мнение отвечает за обработку ввода. Это немного искажает цель и концепцию «взгляда». Как в MVP, так и в MVC представление должно быть настолько «глупым», насколько это возможно, и на самом деле не должно отвечать за обработку чего-либо ... команды, действия, ввод и т. Д. Должны находиться в ведении контроллера или докладчика.

Видя, что ваше представление на самом деле является консольным приложением, а не приложением веб-форм (что и было моим первоначальным предположением), я думаю, что MVC может действительно лучше соответствовать вашим потребностям. MVP - это хорошее решение для устранения недостатков ASP.NET WebForms, но оно не так эффективно и не помогает в решении отдельных проблем, как MVC. Я хотел бы изучить реализацию шаблона MVC, который изначально был разработан для приложений консольного типа. Контроллер становится центральным обработчиком ввода, который затем выдает команды для обработчиков команд и вашей модели. Тогда представление будет чистым и верным для формирования ... только отображение информации и ничего больше.

Если есть какая-то причина, по которой вы не можете использовать подход MVC, который, на мой взгляд, был бы идеальным, и должен использовать MVP, я могу предложить больше советов о том, как вы можете исправить текущую реализацию. Однако я настоятельно рекомендую изучить использование MVC, поскольку эти шаблоны изначально были разработаны для решения той самой проблемы, которую вы пытаетесь решить ... в консольных приложениях.

...