POSIX API и принципы разработки SOLID
Хотя принципы проектирования SOLID в основном применяются к объектно-ориентированным системам, существуют некоторые концепции SOLID, которые можно применять к процедурному программированию, такие как SRP или DIP. Но когда я изучил некоторые функции, доступные в POSIX API, я заметил, что некоторые принципы не соблюдаются, хотя это может быть так.
Я возьму в качестве примера SRP и системный вызов sigaction:
- SRP заявляет, что в нашем случае на функцию должна быть возложена одна ответственность, что означает, что изменения в одной части спецификаций нашей системы - это единственное, что может изменить спецификации функции.
- sigaction - системный вызов, используемый для изменения действия, выполняемого процессом при получении сигнала.
sigaction может использоваться для установки базового обработчика вида:
void (*sa_handler)(int)
Это означает, что обработчик получает только номер сигнала для выполнения своего действия. Системный вызов также можно использовать для установки обработчика в форме:
void (*sa_sigaction)(int, siginfo_t*, void*)
Что позволило нам получить больше информации об обработанном сигнале. Обе формы устанавливаются с одним и тем же системным вызовом, благодаря флагам, установленным вызывающей стороной.
С моей точки зрения, sigaction нарушает принцип SRP, поскольку несет ответственность за реализацию обоих типов установки обработчика.
Поэтому мой вопрос: нарушает ли POSIX API принципы SOLID, если да, то почему?
4 ответа
При всем уважении, я думаю, что ваш пример на тонком льду (он также игнорирует D в SOLID).
POSIX может нарушать принципы SOLID (или не может)... но, с другой стороны, POSIX имеет зрелое понимание того, что может быть отделено и что принадлежит друг другу (понимание, которое приходит из практического использования).
Другими словами, вопрос касается сферы действия "что такое отдельная ответственность?", И POSIX имеет многолетний опыт, который помогает ей подвести черту.
В своем примере вы утверждаете, что sigaction
должен реализовывать оба типа чего-то, но это заблуждение.
sigaction
несет единоличную ответственность - он должен зарегистрировать обратный вызов. Тип обратного вызова на самом деле не имеет значения, так как ответственность лежит в "регистрации".
Если массив push
функция будет независимой от типа, будет ли она нарушать принцип SRP? Нет. Это будет нести единственную ответственность - подтолкнуть к массиву. Тоже самое.
Если бы я следовал вашей логике, реализуя разные функции для каждого типа обратного вызова, я обнаружил бы, что снова и снова пишу один и тот же код с небольшими вариациями - это нарушение принципа СУХОЙ, и это явный признак того, что эти функции совместно используют один и тот же код. ответственность и должна быть унифицирована.
POSIX API нарушает принципы SOLID?
Да POSIX - это десятилетия, написанные многими программистами при поддержке IEEE. SOLID относительно новый (по сравнению) и был написан парнем по имени Боб.
POSIX более зрелый, и люди, стоящие за ним, понимают, что аккуратные маленькие аббревиатуры (например, SOLID) не могут объяснить все маленькие исключения в разработке программного обеспечения.
Если вы спросите меня, именно SOLID нарушает POSIX.
Помимо этих принципов, являющихся предметом мнения, POSIX предшествует SOLID на десятилетия. Он также в основном документирует и формализует существующую практику, а не заново изобретает вещи с нуля. Проектирование за комитетом, как правило, представляет собой гораздо большую проблему, чем нарушение педантизма, такого как SRP, так что это почти наверняка хорошая вещь.
Обратите внимание, что некоторые из интерфейсов, фактически разработанных POSIX, в значительной степени следуют принципам разработки ООП, часто такими способами, которые вносят недостатки. Например posix_spawn
не может быть AS-безопасной заменой fork
а также execve
потому что это зависит от создания объекта атрибута. Интерфейсы потоков POSIX также в значительной степени заимствуют у ООП способами, которые обычно ничего не ломают, но делают их бесполезно болезненными для использования.
На самом деле мы не имеем никакого представления о цели, то есть единственной ответственности за конкретную реализацию sa_sigaction, которую вы вызываете.
Однако, если бы мне пришлось угадывать, я ожидал бы, что реализация sa_sigaction является частью интерфейсного модуля, который реализует этот API POSIX поверх низкоуровневых возможностей, специфичных для ОС, и что единственная ответственность функции sa_sigaction заключается в реализации эта конкретная часть спецификации POSIX.
Другими словами, это объект шаблона адаптера, и он несет единственную ответственность.
Возможно, вы хотели сказать, что спецификация POSIX API нарушает SRP... возможно, но это вряд ли имеет значение. SRP предназначен для обеспечения устойчивости вашей системы к изменяющимся требованиям. Как древний стандарт API, POSIX не предъявляет много новых требований. По сути, он документирует, как все было сделано в прошлом, и факты истории не меняются.