Foundation
Фундаментальные принципы
Ещё раз напоминаю себе о фундаментальных принципах.
Фундаментальные принципы программирования
- Никогда не повторяйте свой код в рамках одного проекта. Если вы повторяете код, значит, делаете лишнюю работу которую можно сократить при рациональном подходе.
- Не изобретайте велосипеды. Как правило уже давно всё придумано за вас другими людьми, надо лишь найти готовое решение и приспособить его под свои нужды.
- Используйте готовые библиотеки и фреймворки для экономии времени если условия вашего проекта это позволяют.
- Старайтесь в своих работах использовать только open source, что бы всё было прозрачно для вас.
Шесть принципов программирования
- Модульность.
- Модифицировать.
- Легкость использования.
- Безопасность.
- Стиль.
- Отладка.
Восемь принципов программирования, которые могут облегчить вам жизнь
- Инкапсулируйте то, что изменяется.
- Предпочитайте композицию наследованию.
- Код должен зависеть от абстракций, а не от конкретных реализаций.
- Стремитесь к слабой связности взаимодействующих объектов.
- Классы должны быть открыты для расширения, но закрыты для изменения.
- Взаимодействуйте только с близкими друзьями.
- Не вызывайте нас — мы сами вас вызовем.
- Класс (или метод) должен иметь только одну причину для изменения.
1. Инкапсулируйте то, что изменяется.
Надо выделить компоненты, которые могут измениться, и отделить их от части системы, которая останется неизменной. Инкапсуляция позволит изменить или расширить выделенные компоненты без изменения остальной части системы. Основная проблема здесь в том, как лучше всего разделить приложение на части. Все паттерны проектирования занимаются ответом на этот вопрос.
2. Предпочитайте композицию наследованию.
При композиции поведение не наследуется, а предоставляется для использования правильно выбранным объектом. Так же композиция позволяет изменить поведение объекта, если он подключен не напрямую, а через интерфейс (см. след. принцип). Естественно, везде фанатично применять композицию и совсем отказаться от наследования было бы неразумно.
3. Код должен зависеть от абстракций, а не от конкретных реализаций.
Высокоуровневые компоненты не должны зависеть от низкоуровневых, и те и другие должны зависеть от абстракций. Авторы этой книги называют его принципом инверсии зависимостей (Inversion of Control, IoC). Лучше выделить контракт класса в протокол, а затем реализовать его.
4. Стремитесь к слабой связности взаимодействующих объектов.
Чем меньше объекты знают друг о друге, тем гибче система. Одному компоненту нет необходимости знать о внутреннем устройстве другого.
5. Классы должны быть открыты для расширения, но закрыты для изменения.
Это так называемый принцип «Open Closed». В разные периоды времени его реализовывали разным образом. Бертран Мейер предлагал в своей книге не изменять созданную реализацию класса, а при необходимости внесения изменений расширять класс посредством создания наследников. Позже была выдвинута идея использовать интерфейсы, реализации которых могут быть полиморфно заменены одна на другую при необходимости.
6. Взаимодействуйте только с близкими друзьями.
Это принцип минимальной информированности. При проектировании класса надо обращать внимание на количество классов, с которыми будет происходить его взаимодействие. Чем меньше таких классов, тем гибче система.
7. Не вызывайте нас — мы сами вас вызовем. (Hollywood priciple)
Или голливудский принцип. По Фаулеру — это синоним принципа IoC. Согласно идеи, компоненты высокого уровня (например, интерфейсы) определяют за компоненты низкого уровня (реализации), как и когда им подключаться к системе. Авторы Head First Design Patterns допускают, что согласно этому принципу компоненты низкого уровня могут участвовать в вычислениях без формирования зависимостей с компонентами высокого уровня, и в этом состоит отличие от более жесткого IoC.
8. Класс (или метод) должен иметь только одну причину для изменения.
Это так называемый «принцип одной обязанности». Чем больше причин для изменения, тем больше вероятность изменения. А изменение — причина массы проблем. Принцип указывает на то, что классу (как и методу) должна быть выделена только одна обязанность. Например, в хорошо спроектированной системе с трехслойной архитектурой: один метод DAO делает ровно один запрос в базу, один метод сервиса выполняет ровно одну задачу бизнес-логики, один метод контроллера вызывает сервис ровно один раз.