Плохо ли передавать форму в качестве аргумента классу, чтобы получить доступ к некоторым его переменным или методам? - PullRequest
5 голосов
/ 13 сентября 2011

Я обнаружил, что могу либо передать 8 аргументов конструктору класса, либо просто передать вместо него переменную формы.

Однако, поскольку я не использую все в форме, может показаться, что это плохой дизайн?

Кроме того, к объектам, к которым я обращаюсь, мне нужно предоставить средства доступа.

Это нарушает принципы ООП?

Ответы [ 5 ]

5 голосов
/ 13 сентября 2011

Это зависит от того, используете ли вы форму как конкретный тип формы, и «логически» имеет смысл, что вы работаете с формой, тогда непременно передайте ссылку на форму.

Это как любой другой класс - если бы я собирался получить доступ к элементам «сотрудника», я бы написал:

void DoSomething(Employee employee) { ...

Вместо:

void DoSomething(string firstName, string lastName, DateTime hireDate...) { ...

Первый очень чистый и очевидный.

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

Кроме того, к объектам, к которым я обращаюсь, мне нужно предоставить средства доступа.

Если это так, я подозреваю, что наличие класса, инкапсулирующего данные,вероятно, лучший дизайн ... Форма может предоставлять свойство или метод, который возвращает экземпляр этого класса, и передавать его во второй класс.

3 голосов
/ 13 сентября 2011

Передача формы графического интерфейса другим компонентам графического интерфейса или, что еще хуже, модель / библиотека, которая работает, нарушает инкапсуляцию и создает тесную связь.

Форма должна абстрагировать данные и модель ниже. Другие классы модели или библиотеки должны быть переданы объектам модели. Типичный шаблон - «привязать» графический слой к модели.

Вместо передачи 8 переменных, 8 переменных логически разбиваются на разные объекты? В идеале вы должны передать объект или набор объектов, которые в совокупности могут содержать 8 переменных-членов. Затем вы можете просто передать ссылки на объекты, которые содержатся в той же модели, к которой обращается ваш графический интерфейс.

2 голосов
/ 13 сентября 2011

Не видя класса, я почти гарантирую, что класс, принимающий 8 аргументов, нарушает принцип единой ответственности.Это может быть класс, сгенерированный для представления таблицы в базе данных (или чего-то в этом роде), и в этом случае вы должны инкапсулировать ее в свой собственный класс, передавая ее вместо формы.

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

1 голос
/ 13 сентября 2011

Это обычно , потому что обычно люди ленивы или не понимают, как использовать события, поэтому они пишут такой код:

class MainForm : Form
{
    // stuff
}

class ChildForm : Form
{
    private MainForm _mainFrm;
    public ChildForm( MainForm frm )
    {
        _mainFrm = frm;
    }

    private void someButton_Click( ... )
    {
        _mainFrm.UpdateSomeText();
    }
}

Этот код создает ужасную связь между двумя различными классами пользовательского интерфейса. Теперь, в простом, внутреннем, возможно, одноразовом проекте, это, вероятно, хорошо, и вы можете написать его один раз и двигаться дальше. В целом это означает, что вам вполне может потребоваться изменить класс ChildForm в ответ на изменения в классе MainForm, что нежелательно и его можно избежать с помощью механизмов слабой связи, таких как события.

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

0 голосов
/ 13 сентября 2011

Я могу представить класс, который управляет форматированием формы (шрифт, размер, цвет и т. Д.), Который может принимать переменную типа Form в качестве аргумента.Я мог бы утверждать, что эта структура не будет нарушать ОО-принципы.Ничего, кроме этого, вероятно, нет.

Даже если вам нужны данные о клиенте в новом классе, и у вас возникнет желание передать CustomerForm, который содержит всю необходимую информацию, НЕ ДЕЛАЙТЕ ЭТОГО.Создайте класс клиента, предоставьте экземпляр этого класса из формы и передайте этот экземпляр новому классу.Если вы когда-нибудь измените пользовательский интерфейс или если вам когда-нибудь понадобится автоматизировать часть рабочего процесса, которая раньше была ручной, вы будете рады, что сделали это.

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