Реализован модуль учета финансов с полным функционалом управления счетами, категориями и операциями.
- ✅ Создание, редактирование и удаление счетов (BankAccount)
- ✅ Создание, редактирование и удаление категорий (Category)
- ✅ Создание и удаление операций (Operation)
- ✅ Автоматический пересчет баланса счетов при создании/удалении операций
- ✅ Поддержка Undo/Redo для всех операций
- ✅ Аналитика: подсчет разницы доходов/расходов, группировка по категориям, аналитика за все время
- ✅ Импорт/экспорт: поддержка форматов CSV, YAML, JSON
- ✅ Управление данными: автоматический и ручной пересчет баланса
- ✅ Статистика: измерение времени выполнения команд через паттерн Декоратор
Каждый класс имеет одну ответственность:
- Фабрики (
BankAccountFactory,CategoryFactory,OperationFactory) - создание объектов с валидацией - Репозитории (
InMemoryBankAccountRepository,InMemoryCategoryRepository,InMemoryOperationRepository) - хранение данных - Фасады (
BankAccountFacade,CategoryFacade,OperationFacade,AnalyticsFacade) - высокоуровневый API - Команды - инкапсуляция пользовательских сценариев
- FileService - работа с файловой системой
- MenuUI - отображение пользовательского интерфейса
Система открыта для расширения, закрыта для модификации:
- Новые форматы экспорта через
IExportVisitor(без изменения существующего кода) - Новые форматы импорта через наследование от
BaseImportTemplate - Новые команды через реализацию
ICommand
Все реализации интерфейсов взаимозаменяемы:
BankAccountRepositoryProxyзаменяетInMemoryBankAccountRepositoryчерезIBankAccountRepository- Все посетители взаимозаменяемы через
IExportVisitor - Все шаблоны импорта взаимозаменяемы через
IImportTemplate
Интерфейсы разделены по назначению:
IBankAccountRepository,ICategoryRepository,IOperationRepository- отдельные интерфейсы для каждой сущности- Каждый интерфейс содержит только необходимые методы
Высокоуровневые модули не зависят от низкоуровневых:
- Фасады зависят от интерфейсов репозиториев, а не от конкретных реализаций
- Все зависимости инжектируются через конструкторы
- Используется DI-контейнер
Microsoft.Extensions.DependencyInjection
Классы объединяют функционально связанные операции:
BankAccountFacade- все операции со счетамиAnalyticsFacade- вся аналитикаBaseImportTemplate- общая логика импорта
Классы слабо связаны между собой:
- Фасады зависят только от интерфейсов репозиториев и фабрик
- Команды зависят только от фасадов
- Посетители работают через интерфейс
IExportVisitor
Классы: BankAccountFacade, CategoryFacade, OperationFacade, AnalyticsFacade
Где используется: В CommandProcessor для выполнения команд, в BaseImportTemplate для импорта данных
Обоснование: Упрощает работу с системой, объединяя множество операций в простые методы высокого уровня. Скрывает сложность системы от клиентского кода.
Важность: Упрощает API, уменьшает связанность клиентского кода с внутренней структурой.
Классы: ICommand, IUndoableCommand, CreateAccountCommand, UpdateAccountCommand, DeleteAccountCommand, CreateCategoryCommand, UpdateCategoryCommand, DeleteCategoryCommand, CreateOperationCommand, DeleteOperationCommand
Где используется: В CommandProcessor.Process() - все команды создаются и выполняются через этот метод. Поддержка Undo/Redo через стеки _undoStack и _redoStack.
Обоснование: Каждый пользовательский сценарий инкапсулирован в отдельную команду. Позволяет логировать выполнение, отменять операции (undo/redo), измерять время выполнения.
Важность: Инкапсулирует запросы, позволяет параметризовать клиентов операциями, поддерживает очередь запросов и логирование.
Классы: TimingCommandDecorator, TimingCommandWithResultDecorator<TResult>
Где используется: В CommandProcessor.Process() - команды оборачиваются в TimingCommandDecorator для измерения времени выполнения
Обоснование: Добавляет функциональность измерения времени выполнения команды, не изменяя саму команду.
Важность: Позволяет динамически добавлять новое поведение объектам, не изменяя их структуру. Следует принципу OCP.
Классы: BaseImportTemplate (абстрактный), JsonImportTemplate, YamlImportTemplate, CsvImportTemplate
Где используется: В CommandProcessor.ImportData() - выбирается нужный шаблон импорта в зависимости от расширения файла
Обоснование: Общая логика импорта (чтение файла, обработка данных) одинакова для всех форматов, отличается только парсинг данных. Шаблонный метод определяет алгоритм, делегируя шаги подклассам.
Важность: Избегает дублирования кода, обеспечивает единый алгоритм импорта для всех форматов.
Классы: IExportVisitor, ExportData, JsonExportVisitor, YamlExportVisitor, CsvExportVisitor
Где используется: В CommandProcessor.ExportData() - выбирается нужный посетитель в зависимости от выбора пользователя
Обоснование: Экспорт данных в различные форматы - это операция, которая зависит от типа формата. Посетитель позволяет добавить новую операцию (новый формат) без изменения классов данных.
Важность: Разделяет алгоритмы от структуры объектов, позволяет легко добавлять новые форматы экспорта.
Классы: IBankAccountFactory, BankAccountFactory, ICategoryFactory, CategoryFactory, IOperationFactory, OperationFactory
Где используется: В фасадах (BankAccountFacade, CategoryFacade, OperationFacade) - все объекты создаются через фабрики
Обоснование: Все доменные объекты создаются через фабрики, которые обеспечивают валидацию. Гарантирует создание только валидных объектов (например, Operation не может иметь отрицательный amount).
Важность: Инкапсулирует процесс создания объектов, обеспечивает валидацию в одном месте, предотвращает создание невалидных объектов.
Классы: BankAccountRepositoryProxy
Где используется: Зарегистрирован в DI контейнере через метод Decorate() в ServiceCollectionExtensions.AddBankHSE(). Прокси оборачивает InMemoryBankAccountRepository и добавляет кэширование.
Обоснование: Прокси добавляет in-memory кэширование для репозитория счетов. При первом обращении данные загружаются в кэш, последующие обращения работают с кэшем.
Важность: Прозрачно добавляет дополнительную функциональность (кэширование) без изменения клиентского кода и реального репозитория. Следует принципу OCP.
Проект использует Microsoft.Extensions.DependencyInjection для управления зависимостями. Все сервисы регистрируются в методе ServiceCollectionExtensions.AddBankHSE().
Преимущества: слабая связанность между компонентами, легкое тестирование, централизованная конфигурация зависимостей.
BankHSE/
├── Domain/ # Доменный слой
│ ├── Entities/ # Доменные сущности
│ ├── Factories/ # Фабрики
│ ├── Helpers/ # IdGenerator
│ └── Repositories/ # Интерфейсы репозиториев
├── Application/ # Слой приложения
│ ├── Facades/ # Фасады
│ ├── Commands/ # Команды
│ │ └── Decorators/ # Декораторы
│ ├── Analytics/ # Аналитика
│ ├── Balance/ # Пересчет баланса
│ ├── Export/ # Экспорт (Посетитель)
│ ├── Import/ # Импорт (Шаблонный метод)
│ ├── Services/ # FileService
│ ├── UI/ # MenuUI
│ └── Helpers/ # InputHelper
├── Infrastructure/ # Инфраструктурный слой
│ ├── Repositories/ # Реализации репозиториев
│ ├── Proxy/ # Прокси
│ └── DependencyInjection/ # Конфигурация DI
└── Program.cs # Точка входа
git clone https://github.com/Akim112/hse-bank-system.git
cd hse-bank-systemdotnet restore
dotnet build
dotnet run --project BankHSE/BankHSE.csprojПосле запуска откроется интерактивное меню с возможностями:
- Управление счетами (создание, редактирование, удаление, просмотр)
- Управление категориями (создание, редактирование, удаление, просмотр)
- Управление операциями (создание, удаление, просмотр)
- Аналитика (за период или за все время)
- Пересчет баланса счетов
- Экспорт/импорт данных (JSON, YAML, CSV)
- Undo/Redo операций
Файлы экспорта/импорта сохраняются в текущей рабочей директории приложения.