1. Статика против экземпляра
Я думаю, что есть очень четкие рекомендации о том, что такое хороший ОО дизайн, а что нет. Проблема в том, что блогосфера затрудняет отделение хорошего от плохого и безобразного. Вы можете найти какой- то справочник, поддерживающий даже худшую практику, о которой вы только можете подумать
И худшая практика, о которой я могу подумать, - это Global State, включая упомянутую вами статику и любимый всеми синглтон. Некоторые выдержки из классической статьи Миско Хевери на эту тему .
Чтобы действительно понять зависимости, разработчики должны прочитать каждую строку кода. Это вызывает Spooky Action на расстоянии: при запуске наборов тестов глобальное состояние, измененное в одном тесте, может вызвать неожиданный сбой последующего или параллельного теста. Прервите статическую зависимость, используя ручное или Guice внедрение зависимости.
Spooky Action на расстоянии - это когда мы запускаем одну вещь, которая, по нашему мнению, изолирована (так как мы не передали никаких ссылок), но неожиданные взаимодействия и изменения состояния происходят в удаленных местах системы, о которых мы не говорили объекту. Это может произойти только через глобальное состояние.
Возможно, вы не думали об этом раньше, но всякий раз, когда вы используете статическое состояние, вы создаете секретные каналы связи и не делаете их понятными в API. Spooky Action на расстоянии заставляет разработчиков читать каждую строку кода, чтобы понять потенциальные взаимодействия, снижает производительность труда разработчиков и вводит в заблуждение новых членов команды.
Это сводится к тому, что вы не должны предоставлять статические ссылки на все, что имеет какое-то сохраненное состояние. Единственное место, где я использую статику - это перечисляемые константы, и у меня есть опасения даже по этому поводу.
2. Методы с входными параметрами и возвращаемыми значениями по сравнению с методами без
Вы должны понять, что методы, которые не имеют входных параметров и выходных параметров, в значительной степени гарантированно будут работать в каком-то внутреннем состоянии (иначе, что они делают?). Есть целые языки , которые построены на идее избегания сохраненного состояния.
Каждый раз, когда вы сохраняете состояние, у вас есть возможность побочных эффектов, поэтому убедитесь, что вы всегда используете его внимательно. Это подразумевает, что вам следует отдавать предпочтение функциям с определенными входами и / или выходами.
И, на самом деле, функции, которые определили входы и выходы, гораздо проще протестировать - вам не нужно запускать здесь функцию и смотреть туда, чтобы увидеть, что произошло, и вам не нужно где-то устанавливать свойство иначе, прежде чем запускать тестируемую функцию.
Вы также можете безопасно использовать этот тип функции в качестве статики. Однако я бы этого не сделал, потому что, если бы потом мне захотелось где-то использовать немного другую реализацию этой функции, вместо того, чтобы предоставить другой экземпляр новой реализации, я застрял без возможности заменить функциональность.
3. Перекрывающиеся против Различных
Я не понимаю вопроса. Каким будет преимущество в двух перекрывающихся методах?
4. Частное против публичного
Не выставляйте ничего, что вам не нужно подвергать. Тем не менее, я не большой поклонник частного, либо. Я не разработчик C #, но разработчик ActionScript. Я потратил много времени на код Adobe Flex Framework, который был написан около 2007 года. И они сделали очень плохой выбор того, что делать приватным, что превращает их в кошмар, пытаясь расширить свои классы.
Таким образом, если вы не считаете себя лучшим архитектором, чем разработчики Adobe примерно в 2007 году (из вашего вопроса я бы сказал, что у вас есть еще несколько лет, прежде чем у вас появится возможность заявить об этом), вы, вероятно, захотите просто по умолчанию использовать защищенный ,
Есть некоторые проблемы с вашими примерами кода, которые означают, что они плохо спроектированы, поэтому невозможно выбрать A или B.
Во-первых, вы, вероятно, должны отделить создание вашего объекта от его использования . Таким образом, вы обычно не имеете new XMLReader()
права рядом с тем, где оно используется.
Кроме того, как говорит @djna, вы должны инкапсулировать методы, используемые в вашем XML Reader, так что ваш API (пример экземпляра) может быть упрощен до:
_document Document = reader.read(info);
Я не знаю, как работает C #, но, поскольку я работал с рядом веб-технологий, я подозреваю, что вы не всегда сможете сразу вернуть XML-документ (за исключением, возможно, в качестве обещания или будущего типа). объект), но я не могу дать вам совет о том, как обрабатывать асинхронную загрузку в C #.
Обратите внимание, что при таком подходе вы можете создать несколько реализаций, которые могут принимать параметр, который сообщает им, где / что читать и возвращать объект XML, и менять их в зависимости от потребностей вашего проекта. Например, вы можете читать напрямую из базы данных, из локального хранилища или, как в исходном примере, с URL-адреса. Вы не можете сделать это, если вы используете статический метод.