Контакт с “глобальными” структурами данных в объектно-ориентированном мире

Вам не хватает u.username в group by, также COUNT(a.id) должно измениться на COUNT(distinct a.id):

SELECT u.id, u.username, COUNT(distinct a.id) AS total_articles, COUNT(c.id) AS total_comments FROM users u
LEFT JOIN articles a ON u.id = a.user_id
LEFT JOIN comments c ON a.id = c.article_id
GROUP BY u.id, u.username;

Обновление:

Однако, я думаю, что, что вам на самом деле нужно что-то другое, чем предложенный вами запрос. Вы сказали, что вам нужно общее количество статей для каждого пользователя и общее количество комментариев для каждой статьи . Это означает, что вам нужно два отдельных запроса:

SELECT a.id article_id , COUNT(c.id) AS total_comments
FROM articles a 
LEFT JOIN comments c ON a.id = c.article_id
GROUP BY a.id

SELECT u.id, u.username, COUNT(distinct a.id) AS total_articles
FROM users u
LEFT JOIN articles a ON u.id = a.user_id
GROUP BY u.id, u.username;
15
задан Brad Richards 1 October 2008 в 08:59
поделиться

9 ответов

Глобальные данные не являются настолько же неправильными, как требуют многие пуристы OO!

, В конце концов, при реализации классов OO у Вас есть обычно использование API к Вашей ОС. Какого черта это, если это не огромная груда глобальных данных и сервисов!

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

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

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

9
ответ дан 1 December 2019 в 04:10
поделиться

Вы могли бы хотеть думать об изменении требования, чтобы много объектов знало о тех же структурах данных. Одна причина там, кажется, не чистое OO, которым способ обменяться данными состоит в том, что обмен данными не очень объектно-ориентирован.

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

2
ответ дан 1 December 2019 в 04:10
поделиться

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

Так, по моему опыту, если Вы делаете 3), Вы в конечном счете закончите тем, что делали 1) в два раза стоимость.

Идут для 1, и быть мелкомодульным, о каких структурах данных Вы ссылаетесь от каждого объекта. Не используйте "объекты контекста", просто передавайте в точно необходимых данных. Да, это делает код более сложным, но зато, это делает это более ясным - то, которое FwurzleDigestionListener содержит ссылку и на Fwurzle и на DigestionTract, сразу дает читателю общее представление о его цели.

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

4
ответ дан 1 December 2019 в 04:10
поделиться

Мне не нравится ни одно из Ваших предлагаемых решений:

  1. Вы раздаете набор объектов "контекста" - вещи, которые используют их, не определяют, какие поля или части данных они действительно интересуются
  2. , Посмотрите здесь для описания Объект Бога шаблон. Это хуже из всех миров
  3. , Просто никогда не используют объекты Singleton ни для чего. Вы, кажется, определили несколько потенциальных проблем сами
-2
ответ дан 1 December 2019 в 04:10
поделиться

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

не становятся слишком одержимыми тем, придерживаетесь ли Вы просто одной методологии программирования или другого, найдите решение, которое соответствует Вашей проблеме. Я думаю, что существуют совершенно допустимые контексты для одиночных элементов (Регистрирующийся, например).

1
ответ дан 1 December 2019 в 04:10
поделиться

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

1
ответ дан 1 December 2019 в 04:10
поделиться

Опция 3), в то время как не пуристское OO, имеет тенденцию быть самым разумным решением. Но я не сделал бы Ваш класс одиночным элементом; и используйте некоторый другой объект в качестве статического 'словаря' для управления теми совместно используемыми ресурсами.

0
ответ дан 1 December 2019 в 04:10
поделиться

Мы должны заботиться, чтобы не перепутать Объектно-ориентированное проектирование с Объектно-ориентированной Реализацией. Al слишком часто, термин, Дизайн OO используется для оценки реализации, так же, как, по моему скромному мнению, это здесь.

Дизайн

Если в Вашем дизайне Вы видите много объектов, имеющих ссылку на точно тот же объект, который означает много стрелок. Разработчик должен чувствовать зуд здесь. Он должен проверить, является ли этот объект просто наиболее часто используемым, или если это - действительно утилита (например, фабрика COM, реестр некоторого вида...).

От требований проекта он видит, должен ли это действительно быть одиночный элемент (например, 'Интернет'), или если объект совместно используется, потому что это слишком общее или слишком дорогим или безотносительно.

Реализация

Когда Вас просят реализовать Дизайн OO на языке OO, Вы сталкиваетесь с большим количеством решений, как то, которое Вы упомянули: как я должен реализовать все стрелки к часто используемому объекту в дизайне?

В этом суть, где вопросы рассмотрены о 'статическом участнике', 'глобальной переменной', 'класс бога' и 'a-lot-of-function-arguments''.

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

1
ответ дан 1 December 2019 в 04:10
поделиться

Я использую комбинацию наличия одного глобального объекта и передачи интерфейсов на пути конструкторы.

От одного основного глобального объекта (обычно называемый в честь того, чем Вашу программу называют или делает), можно запустить другой globals (возможно, которые имеют их собственные потоки). Это позволяет Вам управлять установкой объектов программы в конструкторе основных объектов и разъединении их снова в правильном порядке, когда приложение останавливается в этом деструкторе основных объектов. Используя статические классы непосредственно делает это хитрым для инициализирования/деинициализирования любых ресурсов эти классы использование управляемым способом. Этот основной глобальный объект также имеет свойства для того, чтобы достигнуть интерфейсы различных подсистем Вашего приложения, которым различные объекты могут хотеть овладеть, чтобы сделать их работу.

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

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

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

1
ответ дан 1 December 2019 в 04:10
поделиться