Пользователь
0,0
рейтинг
28 марта 2012 в 01:01

Разработка → Восемь принципов программирования, которые могут облегчить вам жизнь

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

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

2. Предпочитайте композицию наследованию.
При композиции поведение не наследуется, а предоставляется для использования правильно выбранным объектом. Так же композиция позволяет изменить поведение объекта, если он подключен не напрямую, а через интерфейс (см. след. принцип). Естественно, везде фанатично применять композицию и совсем отказаться от наследования было бы неразумно.

3. Код должен зависеть от абстракций, а не от конкретных реализаций.
Высокоуровневые компоненты не должны зависеть от низкоуровневых, и те и другие должны зависеть от абстракций. Авторы этой книги называют его принципом инверсии зависимостей (Inversion of Control, IoC). Лучше выделить контракт класса в интерфейс, а затем реализовать его. Например вместо:

private ArrayList<String> someList = new ArrayList<String>();

надо писать:

private List<String> someList= new ArrayList<String>();

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

private List<String> someList= new LinkedList<String>();

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

5. Классы должны быть открыты для расширения, но закрыты для изменения.
Это так называемый принцип «Открытости/закрытости». В разные периоды времени его реализовывали разным образом. Бертран Мейер предлагал в своей книге не изменять созданную реализацию класса, а при необходимости внесения изменений расширять класс посредством создания наследников. Позже была выдвинута идея использовать интерфейсы, реализации которых могут быть полиморфно заменены одна на другую при необходимости.

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

7. Не вызывайте нас – мы сами вас вызовем.
Или голливудский принцип. По Фаулеру – это синоним принципа IoC. Согласно идеи, компоненты высокого уровня (например, интерфейсы) определяют за компоненты низкого уровня (реализации), как и когда им подключаться к системе. Авторы Head First Design Patterns допускают, что согласно этому принципу компоненты низкого уровня могут участвовать в вычислениях без формирования зависимостей с компонентами высокого уровня, и в этом состоит отличие от более жесткого IoC.

8. Класс (или метод) должен иметь только одну причину для изменения.
Это так называемый «принцип одной обязанности». Чем больше причин для изменения, тем больше вероятность изменения. А изменение – причина массы проблем. Принцип указывает на то, что классу (как и методу) должна быть выделена только одна обязанность. Например, в хорошо спроектированной системе с трехслойной архитектурой: один метод DAO делает ровно один запрос в базу, один метод сервиса выполняет ровно одну задачу бизнес-логики, один метод контроллера вызывает сервис ровно один раз.

Практически все принципы пересекаются друг с другом, у всех задача одна и та же – уменьшение сложности системы и, как следствие, жизни программистов. Хочется верить, что чья-то жизнь станет легче после прочтения =)

Upd.: Господа, которые ссылаются на Head First Java Patterns: это не первая и не последняя книга, в которой были описаны эти принципы. В этом можно убедиться, прочитав, например:
Martin Fowler, Patterns of Enterprise Application Architecture
Kent Beck, Implementation Patterns
Andrew Hunt, David Thomas, The Pragmatic Programmer
Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
Maxim @mrmaxim
карма
2,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (39)

  • –12
    Я предпочитаю руководствоваться этими принципами пиши-код-блять.рф
    • 0
      По себе знаю — без тестирования не обойтись
      Правда я сначала пишу код как мне удобно, потом пишу тесты, потом подгоняю под тесты (хотя считается, что нужно наоборот, но у меня подход такой: сначала — идея, потом реализация, потом тестирование, в запутанных случаях отладка).

      Кстати, есть ли какой-нибудь gpl инструмент для проверки coverage для с++?
      • 0
        gcov?
      • 0
        Bulls Eye кажется
    • +1
      Эти принципы совсем-совсем не про то.
  • +13
    Сильно, но чтоб понять что тут написано нужен серьезный опыт. Примеры выстрелов в ногу привели бы что-ли?
  • +12
    Статья-тезисов, Patterns Head First в кратком изложении
  • +5
    Источник Эрик Фримен?
    • +2
      И Элизабет Фримен
      • +8
        И Гордон
      • 0
        А также Берт Бейтс и Кэти Сьерра.
  • +3
    Давно стемлюсь к сильной связности, но слабой связанности.
    • 0
      По этой причине адекватному переводчику желательно использовать англоязычные термины хотябы в скобках, для начинающего разработчика и так в порядке вещей путаться в coupling и coherence, чтобы дополнительно путать его переводам.
      Мневмоправило (хотя и не идеально отражающее соотношение сущностей):
      coupling — от couple, парочки, парочки зависят друг от друга.
      coherense — согласованность, парочка согласна делать ремонт вместе.
  • +4
    Принципы в статье хорошо перекликаются с SOLID.

    >… у всех задача одна и та же – уменьшение сложности системы и, как следствие, жизни программистов.

    А вот это — пугает :)
  • +6
    Лучше уж подробней изложить про основной императив снижения сложности, выделенный МакКоннелом в его формулировках, чем запоздалые на 10-15 перепевки Code complete авторами из разряда «лишь бы засветиться» со всякими введенными принципами имени себя, лишь что-то необычное сказать, которые стройного видения области в голове не формируют.

    Что касается тезисов, то не читав оригинала и не понимая о чем идет речь можно придраться к каждому второму слову, просто для примера:

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

    Что представляют из себя «неизменные» части и как их определить до окончания разработки?

    >Естественно, везде фанатично применять композицию и совсем отказаться от наследования было бы неразумно.

    Ну и когда же ее в итоге применять? Есть же два элементарных вопроса, которые надо надо задавать при создании модели взаимодействия классов «Являются ли B, C, D разновидностью A?» или «Состоит ли A из B, C, D?», ответ на который достаточно однозначно говорит об уместности того или иного подхода.
    «Используйте как можно чаще, но не злоупотребляйте» — это рекомендация ни о чем.

    И т.д.
  • 0
    Хм. похоже, половину принципов я уяснил для себя интуитивно.
    • +1
      А эт распространная ситуация — человек интуитивно использует какой-нибудь принцип или паттерн, при этом не знает как это все формально называется. ИМХО, эт естественно и даже хорошо — лучше органично сделать, при этом заюзать все паттерны\принципы, что надо, чем зная кучу названий, не уметь их применять.
      Ну а в идеале — знать и применять, конечно же :)
      • 0
        По этому поводу вспоминается холивар на тему подгонки кода под unit-тесты…
        я начал писать на C# в феврале, а смотря на свой код после прочтения статьи понял что использую вполне спокойно и считаю это логичным
        • 0
          Ну надо не подгонять. Надо писать в соответствие с требованиями к кусочку кода, которые выражены в виде юнит-тестов
  • –3
    В общем используйте Spring )
  • +1
    Это всё перевод или персональный опыт автора? Если перевод, то кто источник и где?
    • 0
      Это не перевод, а выдержки из переведенной книги. Автор, кстати, на нее ссылается в 7 пункте.
      • 0
        По моему, эта книга лидер по цитированию на Хабре
    • 0
      тоже возникло ощущение некоторого дежавю…
  • +2
    SOLID + Правило Деметры — короткий пересказ статьи.
  • 0
    а мне очень напомнило Code Complete)
    • 0
      только вместо логики туман и путаница
  • +2
    Уважаемый автор, чья-то жизнь станет легче не после вашей статьи (заметки), а после прочтения книги, из которой вы все эти принципы позаимствовали.
    • 0
      В дополнение к книге, которую вы посоветовали, принципы проектирования классов и сборок подробно описаны в книге www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258
    • 0
      Для тех, кто хочет эту книгу купить, я бы рекомендовал посмотреть на Амазоне. Даже с учетом недешевой доставки, это все равно будет раза в полтора дешевле, чем по ссылке выше. Ну и есть русская версия, однако что там с качеством перевода я не знаю.
      • 0
        К сожалению, с оригиналом я не знаком, но русская версия вызвала у меня исключительно положительные эмоции!
  • –1
    Не хватает:
    9. Принцип замещения Лисков.
  • 0
    Уже много-много лет эти принципы гуляют по интернету, много много юных падаванов их выучило наизусть и все же много-много их на собеседовании валятся при банальном вопросе: «зачем нужны интерфейсы?», «что такое полиморфизм».

    Это как раз яркий пример где теория без практики — ничто. Пока ты мозолями своими не перестроишь сознание на объектный уровень, пока не поймешь удобство, скорость, качество объектного программирования. Пока не покроешь пару проектов юнит тестами и не поймешь что такое зависимости, все эти тезисы звучат как абракадабра.
    • 0
      а я вот вижу кучу ссылок на мсдн по использованию интерфейсов и делегатов.
      код, красивый, работает.
      но что это и нафига оно нужно — до сих пор понять не могу. и как его исполдьзовать тоже.
      Взял книгу по шарпу — Троелсена, там тоже описано, но сути я так и не понял (
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Было бы интересно узнать. Спасибо.
          просто я со следующей зарплаты хочу брать книгу по паттернам еще, в дополнение к Троелсену

          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Похоже, Вы «изобрели» паттерн Наблюдатель.
  • НЛО прилетело и опубликовало эту надпись здесь

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.