Имейте в виду показатель стабильности Мартина и то, что он подразумевает под «стабильностью»:
Instability = Ce / (Ca+Ce)
Или:
Instability = Outgoing / (Incoming+Outgoing)
То есть пакет считается полностью нестабильным, если все его зависимости являются исходящими: он использует другие вещи, но ничто его не использует. В этом случае имеет смысл только, чтобы эта вещь была конкретной. Это также будет самый простой вид изменения кода, так как ничто другое не использует его, и поэтому ничто другое не может сломаться, если этот код изменен.
Между тем, когда у вас есть противоположный сценарий полной «стабильности» с пакетом, используемым одной или несколькими вещами, но он ничего не использует сам по себе, например, центральный пакет, используемый программным обеспечением, тогда Мартин говорит, что эта вещь должна быть Аннотация. Это также подкрепляется частью DIP SOLI (D), принципом инверсии зависимостей, который в основном утверждает, что зависимости должны равномерно перетекать в абстракции как для кода низкого, так и высокого уровня.
То есть зависимости должны равномерно перетекать в сторону «стабильности», а точнее, зависимости должны перетекать в пакеты с большим количеством входящих зависимостей, чем исходящих, и, кроме того, зависимости должны перетекать в абстракции. Суть обоснования этого заключается в том, что абстракции предоставляют передовую возможность для замены одного подтипа на другой, предлагая такую степень гибкости для конкретных частей, реализующих интерфейс, чтобы изменить его, не нарушая входящие зависимости для этого абстрактного интерфейса.
Существуют ли существенные недостатки в зависимости от абстракций?
Ну, я на самом деле не согласен с Мартином здесь, по крайней мере, в отношении моего домена, и здесь мне нужно ввести новое определение «стабильности», как «отсутствие причин для изменений». В этом случае я бы сказал, что зависимости должны стремиться к стабильности, но абстрактные интерфейсы не помогают, если абстрактные интерфейсы нестабильны (по моему определению «неустойчивые», как в случае склонности к многократным изменениям, а не Мартина). Если разработчики не могут получить правильные абстракции и клиенты неоднократно меняют свое мнение таким образом, что абстрактные попытки моделировать программное обеспечение становятся неполными или неэффективными, мы больше не выигрываем от расширенной гибкости абстрактных интерфейсов для защиты системы от каскадных изменений, нарушающих зависимость , В моем личном случае я нашел двигатели ECS, такие как те, что найдены в играх ААА,наиболее конкретный : к необработанным данным, но такие данные очень стабильны (например, «вряд ли когда-либо нужно будет менять»). Я часто находил вероятность того, что что-то, требующее будущих изменений, было бы более полезным показателем, чем отношение эфферентных к общему количеству связей при принятии решений SE.
Поэтому я бы немного изменил DIP и просто сказал бы, что «зависимости должны течь к компонентам, которые с наименьшей вероятностью требуют дальнейших изменений», независимо от того, являются ли эти компоненты абстрактными интерфейсами или необработанными данными. Все, что для меня имеет значение, - это вероятность того, что они могут потребовать непосредственного изменения дизайна. Абстракции полезны только в этом контексте стабильности, если что-то, будучи абстрактным, уменьшает эту вероятность.
Во многих случаях это может иметь место с приличными инженерами и клиентами, которые предвосхищают потребности программного обеспечения в первоначальной разработке и проектируют стабильные (как в неизменяемых) абстракции, в то время как эти абстракции предоставляют им все возможности, необходимые для замены конкретных реализаций. Но в некоторых областях абстракции могут быть нестабильными и склонными к неадекватности, в то время как данные, необходимые для движка, могут быть намного проще предвидеть и заранее сделать стабильными. Таким образом, в этих случаях это может быть более выгодно с точки зрения удобства сопровождения (простота изменения и расширения системы), когда зависимости направляются к данным, а не к абстракциям. В ECS наиболее нестабильные части (как в наиболее часто изменяемых частях) обычно представляют собой функциональные возможности, находящиеся в системах (PhysicsSystem
Например, в то время как наиболее стабильные части (как, по крайней мере, вероятно, будут изменены) являются компонентами, которые просто состоят из необработанных данных ( MotionComponent
например,), которые используют все системы.