Как будет лучше, с точки зрения ООП, спроектировать программу
Лишь на примере классов у меня есть на данный момент 2 класса и форма которая их запускает. В первом классе у меня идет сравнение файлов (будем называть класс Compare), в нем же происходит их сбор. Сравнение отличается от того, какой тип подключения выбран. Их пока что два, к серверу или не к серверу. Второй класс идет выгрузка файлов (будем называть Upload). Он может загружать как на сервер, так и на физ носитель. Зависит от типа выбранного подключения. Также для всего этого нужно совершать подключение к серверу (если выгрузка на сервер), пока что у меня этим занимается форма. Интересно было бы сделать программу про принципу SOLID. Просто потому что, а почему бы и нет. Знания лишними не будут. Именно по всем пунктам мне не нужно, я просто не совсем понял как мне классы разбить, чтобы было читаемо и дополняемо.
А теперь про код.
Кода там много и я его писал давно, сейчас решил его разобрать и переделать удобно, чтобы взять под учебный проект, поэтому смысла от того, что я его сюда вставлю будет немного. Могу лишь структуру еще раз кратко написать.
класс Compare - Методы: Collect, Compare, CompareServer. Возвращает список файлов.
класс Upload - Методы: Upload, UploadInServer
Form - Connect
P.S. UploadInServer и CompareServer на самом деле не существуют, они вызываются перегрузкой метода Upload и Compare. То есть не UploadInServer, а Upload(HttpClient client, List<string> fileList)
Ответы (1 шт):
С точки зрения поставленной задачи изменяемыми или расширяемыми в перспективе функциями являются сравнение файлов и их выгрузка. Соответственно добавление или изменение этого функционала не должно затрагивать уже написанный код (OCP). В данном случае это форма, но это существенной роли не играет. Для того-что бы добиться желаемого результата подходит паттерн Стратегия - https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D1%80%D0%B0%D1%82%D0%B5%D0%B3%D0%B8%D1%8F_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F).
Выделяем два интерфейса:
public interface IFileCompareStrategy
{
//методы необходимые для сравнения фалов
...
public bool IsSatisfied(ConnectionType connectionType)
}
public interface IFileUploadStrategy
{
//методы необходимые для выгрузки файла
...
public bool IsSatisfied(ConnectionType connectionType)
}
public enum ConnectionType
{
Local,
Remote
}
Далее реализуем каждую стратегию для каждого типа соединения. Сюда переезжает вся логика связанная с конкретным действием (SRP). Так же надо учесть что, интеhфейс не должен зависеть от деталей (IOC), то есть надо реализовать два загрузчика файлов, один из которых передает данные по Http, то не надо переопределять метод Upload и передавать туда HttpClient, конкретная реализация HttpFileUploadStrategy должна инкапсулировать HttpClient внутри себя, к примеру инициализацией в конструкторе.
Для чего в каждом интерфейсе определен метод bool IsSatisfied. Данный метод определяет критерий применимости той или иной стратегии, в этот метод передается некий контекст исходя из которого определяется применимость той или иной стратегии. Что позволяет нам написать неизменяемый код (OCP) в вызывающим коде. В данном случае это форма, в которой необходимы заинжектить все реализованные стратегии (DIP). Обычно это делается через конструктор:
public class Form
{
private readonly IEnumerable<IFileCompareStrategy> _compareStrategies;
private readonly IEnumerable<IFileUploadStrategy> _uploadStrategies;
public Form(IEnumerable<IFileCompareStrategy> compareStrategies, IEnumerable<IFileUploadStrategy> uploadStrategies)
{
_compareStrategies = compareStrategies;
_uploadStrategies = uploadStrategies;
}
Далее в месте где происходит выгрузка файлов:
var strategy = _uploadStrategies.Single(s => s.IsSatisfied(currentConnectionType));
strategy.Upload(fileInfo);
Для сравнения файлов аналогично. Тем самым, в дальнейшем, мы можем расширять различные типы выгрузок файлов их сравнения без изменения самого вызывающего кода (в данном случае формы) простым добавление новых типов реализующих интерфейс IFileCompareStrategy или IFileUploadStrategy
Ну и главное помнить, что SOLID это всего лишь принципы. Ваш код не обязан их соблюдать, но должен стремится к этому.