Написание ваших существительных, глаголов, прилагательных - это отличный подход, но я предпочитаю думать о дизайне классов как о том, что нужно задать вопрос, какие данные должны быть скрыты ?
Представьте, что у вас есть Query
объект и Database
объект:
Query
Объект поможет создать и сохранить запрос - магазин, ключ здесь, как функция может помочь вам создать так же легко. Может быть, вы могли бы остаться Query().select('Country').from_table('User').where('Country == "Brazil"')
. Не имеет значения, какой именно синтаксис - это ваша работа! - ключ в том, что объект помогает вам что-то скрыть , в данном случае это данные, необходимые для хранения и вывода запроса. Сила объекта заключается в синтаксисе его использования (в данном случае некоторого умного связывания) и необходимости знать, что он хранит, чтобы заставить его работать. Если все сделано правильно,Query
объект может выводить запросы для более чем одной базы данных. Он внутренне будет хранить определенный формат, но при выводе может легко конвертировать в другие форматы (Postgres, MySQL, MongoDB).
Теперь давайте подумаем об Database
объекте. Что это скрывает и хранит? Совершенно очевидно, что он не может хранить все содержимое базы данных, потому что именно поэтому у нас есть база данных! Так в чем же смысл? Цель состоит в том, чтобы скрыть, как работает база данных от людей, которые используют Database
объект. Хорошие классы упростят рассуждения при манипулировании внутренним состоянием. Для этогоDatabase
объекта вы можете скрыть, как работают сетевые вызовы, или выполнять пакетные запросы или обновления, или обеспечить уровень кэширования.
Проблема в том Database
объект ОГРОМНЫЙ. Он представляет, как получить доступ к базе данных, поэтому под прикрытием он может делать все что угодно. Очевидно, что с сетью, кэшированием и пакетированием довольно сложно справиться в зависимости от вашей системы, поэтому было бы очень полезно скрыть их. Но, как заметят многие, база данных безумно сложна, и чем дальше вы получаете необработанные вызовы БД, тем сложнее настроить производительность и понять, как все работает.
Это фундаментальный компромисс ООП. Если вы выберете правильную абстракцию, это упростит кодирование (String, Array, Dictionary), если вы выберете слишком большую абстракцию (Database, EmailManager, NetworkingManager), она может стать слишком сложной, чтобы действительно понять, как она работает, или что ожидать. Цель состоит в том, чтобы скрыть сложность , но некоторая сложность необходима. Хорошее эмпирическое правило заключается в том, чтобы начать избегать Manager
объектов и вместо этого создавать классы, которые похожи structs
- все, что они делают, это хранят данные, с некоторыми вспомогательными методами для создания / манипулирования данными, чтобы сделать вашу жизнь проще. Например, в случае EmailManager
запуска с вызываемой функцией, sendEmail
которая принимает Email
объект. Это простая отправная точка, и код очень прост для понимания.
Что касается вашего примера, подумайте, какие данные должны быть вместе, чтобы рассчитать то, что вы ищете. Например, если вы хотите узнать, как далеко зашло животное, у вас могут быть AnimalStep
и AnimalTrip
(коллекция AnimalSteps) классы. Теперь, когда каждая Поездка имеет все данные шага, она должна иметь возможность разобраться с этим, возможно, AnimalTrip.calculateDistance()
имеет смысл.