Qt - правильный дизайн кода приложения - PullRequest
5 голосов
/ 01 апреля 2012

Мне было трудно искать соответствующую тему, поэтому вот мой вопрос. Я начал использовать Qt, как два дня назад, и поэтому понятия не имею, как заставить его работать (на стороне кода).

[оффтоп] Вот немного истории: сначала я подумал о том, чтобы отделить логику моего приложения от его внешнего вида. У меня было несколько базовых классов, другие для GUI (отображение и управление) и какие-то «мосты» между, например, перемещением данных из класса A, который имел члены std :: list, в класс B: public QAbstractListView, который QStringList. Но я сдался, когда мне пришлось использовать все больше и больше кода Qt (HTTP-запросы, дисковый ввод-вывод, регулярное выражение). Мой код начал выглядеть как беспорядок, но я подумал о рефакторинге моего кода.

(В любом случае, стоит ли объединить эти две вещи - логику приложения в классах Qt (под)?) [/ Оффтоп]

И я столкнулся с другой проблемой, которая, наконец, связана с вопросом в теме: лучше ли (например, Qt-way) иметь класс с закрытым членом QWebPage и некоторыми открытыми методами, слотами и сигналами для работы? на нем или просто добавить мою функциональность в подкласс QWebPage?

1 Ответ

3 голосов
/ 01 апреля 2012

Наследование является одним из величайших свойств ООП, если оно используется правильно.

«Подкласс» во всех хороших ОО-проектах должен подчиняться простому правилу: является ли ребенок ВИДОМ родительского? В ООП литературе это обычно называют отношениями "есть". И что еще более важно: ребенок всегда должен делать две вещи: специализировать общее поведение или расширять функциональность отца. Я считаю это запахом кода, когда подкласс не делает ни того, ни другого.

Тем не менее, ваше решение не имеет ничего общего с Qt или с тем, что программно лучше или хуже. Это должно иметь смысл.

Пример: если у вас был QLabel, который должен был показывать счет в игре, и только это, было бы неплохо сделать что-то вроде

class MyScoreBoard : public QLabel
{
private:
   int scoreP1;
   int scoreP2;
   Game *_g;
public:
   MyScoreBoard(QWidget *parent = 0) :
       QLabel(parent)
   {
       scoreP1 = 0;
       scoreP2 = 0;
       connect(_g, SIGNAL(scoreChanged(int,int)), this, SLOT(updateScore(int,int)));
   }
public slot:
    updateScore(int a, int b) {
       scoreP1 = a;
       scoreP2 = b;
       this->setText(QString::number(scoreP1) + "x" + QString::number(scoreP2));
    };

};

С другой стороны, если на вашем табло было несколько огней, которые должны мигать всякий раз, когда счет изменился, если у него был один ярлык для каждого игрока, который должен был менять свой цвет в зависимости от счета, то он было бы лучше создать класс ScoreBoard, который имел бы две метки, имел бы две подсветки, а затем реализовать предполагаемое поведение.

Итог: наследовать, если это имеет смысл в вашем дизайне

В Википедии есть хорошая небольшая статья об анти-паттерне, который появляется, когда наследование используется без заботы.

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