Я работаю над проектом, который выполняет множество разных, ужасно сложных вещей, в рамках, который должен быть легко расширяемым другими.
Сначала занятия были большими и делали несколько вещей. Чтобы изменить эти поведения, вам пришлось расширить эти классы. Все методы были виртуальными и не меняли состояние объекта, поэтому было довольно легко сделать это.
Но по мере того, как система росла, стало ясно, что рамки будут в конечном итоге состоять из серии монолитных объектов, каждая из которых имеет цепи наследования looooong. Это также привело к неожиданным зависимостям - абстрактному методу, берущему коллекцию класса X, чтобы создать объект Y, определенный в базовом классе, продиктовало, что EVERYBODY должен был сделать это таким образом, даже если это не имело смысла для половины дерева наследования. Это также привело к массовым классам, которые потребовали десятков единичных тестов, чтобы охватить код более чем на 80%, и сложность была такой, что вы не были уверены, правильно ли вы все охватили. Было очевидно, что этот дизайн может стать очень жестким и негибким.
Итак, мы перепроектировали все по линиям SRP. У вас будет свой интерфейс, базовый класс и, возможно, один или несколько классов реализации. Каждый из них был составлен различных объектов, которые выполняли ключевые функции всего процесса. Если вы хотите изменить одну часть, вы не переопределили метод, вы бы создали другой объект, который расширил требуемый интерфейс/базовый класс и выполнил свою работу по-разному. SRP даже сбрасывался в аргументы и возвращал значения методов класса. Для тех частей системы, которые должны быть гибкими, а не передавать коллекции класса X, которые используются для создания объектов Y, был создан класс для инкапсуляции процесса создания объектов Y. Компоненты системы затем передают этих производителей, объединяют их с другими (ответственность производителей) и в конечном итоге используют их для производства Y. Это позволило создать различные типы производителей, и все это можно было бы рассматривать точно то же самое, хотя они и делали совершенно разные вещи. Этот шаг также резко сократил базу кода каждого класса и сделал их намного проще для тестирования.
Я бы сказал, что, как новый разработчик, ОЧЕНЬ ТРУДНО разбить все до этого уровня. Вам почти нужно написать большой шар грязи, понять, как это работает, а затем перепроектировать его как несколько разных компонентов, каждый из которых несет ответственность за часть целого.
Я думаю, вы должны превратить это в вики, так как нет однозначного ответа. – Will
Я не уверен, что согласен. Я думаю, что их ответы на все более и менее правильные. И я думаю, что слишком много людей считают, что это гораздо более субъективно или контекстно-зависимо, чем на самом деле - отчасти поэтому я разместил вопрос. Спасибо за ваш комментарий. – Thiru