Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
default_stages: [commit]
default_stages: [pre-commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: trailing-whitespace # Removes extra spaces at the end of lines
- id: end-of-file-fixer # Ensures files end with a newline
- id: check-yaml # Validates YAML syntax
- id: check-added-large-files # Prevents committing huge files (>500kb)
- repo: https://github.com/Lucas-C/pre-commit-hooks
rev: v1.5.5
rev: v1.5.6
hooks:
- id: remove-crlf
- id: remove-tabs
Expand All @@ -17,8 +19,3 @@ repos:
- id: google-java-formatter
- id: commitlint
stages: [commit-msg]
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.35.1
hooks:
- id: yamllint
args: [ --strict, -c=.yamllint ]
2 changes: 1 addition & 1 deletion .sdkmanrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
#

java=jdk1.8.0_381
gradle=8.10
gradle=8.0
17 changes: 0 additions & 17 deletions .yamllint

This file was deleted.

2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ val fasterxml = "2.19.2"
val guavaTableVersion = "33.0.0-jre"
val log4jVersion = "2.20.0"
val awaitilityVersion = "4.3.0"
val mockitoVersion = "4.11.0"

dependencies {
// Import the Spring Boot BOM using the platform() function (compatible Java 8)
Expand All @@ -54,6 +55,7 @@ dependencies {
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.mockito:mockito-core")
testImplementation("org.mockito:mockito-junit-jupiter")
testImplementation("org.mockito:mockito-inline:$mockitoVersion")
}

tasks.named<Test>("test") {
Expand Down
64 changes: 64 additions & 0 deletions app/src/main/java/ru/otus/main_patterns/hw05/HW05.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package ru.otus.main_patterns.hw05;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*-
11. Расширяемая фабрика и IoC.
Домашнее задание: Реализация IoC контейнера - частный случай расширяемой фабрики.

Цель: Реализовать собственный IoC контейнер, устойчивый к изменению требований.
В результате выполнения домашнего задания Вы получите IoC, который можно будет использовать в качестве фасада в своих проектах.

Пошаговая инструкция выполнения домашнего задания:
В игре "Космический бой" есть набор операций над игровыми объектами: движение по прямой, поворот, выстрел и т.д.
При этом содержание этих команд может отличаться для разных игр, в зависимости от того, какие правила игры были выбраны пользователями.
У каждой игры свой контекст(scope).
Например, в одной игре пользователи могут ограничить запас каждого корабля некоторым количеством топлива,
а в другой игре запретить поворачиваться кораблям по часовой стрелке и т.д.
IoC может помочь в этом случае, скрыв детали в стратегии разрешения зависимости.

Например:
Command command = IoC<Command>.resolve("двигаться прямо", obj);

,возвращает команду, которая чаще всего является макрокомандой и осуществляет один шаг движения по прямой.

Реализовать IoC контейнер, который:
1. Разрешает зависимости с помощью метода, со следующей сигнатурой:
T IoC.resolve(string key, params object[] args);
Так реализуется параметрический полиморфизм в таких языках, как C++, C#, Java, Kotlin и др.
Указание:
Если язык программирования не поддерживает Generics, как, например, PHP, то запись Вам может быть незнакома.
Тогда возвращайте просто ссылку на базовый класс.
2. Регистрация зависимостей также происходит с помощью метода IoC.resolve(...):
IoC.resolve("ioc.register", "aaa", (args) -> new A()).execute();
3. Зависимости можно регистрировать в разных "scope-ах":
IoC.resolve("ioc.scope.new", "scopeId").execute();
IoC.resolve("ioc.scope.current", "scopeId").execute();

Указание: Если Ваш фреймворк допускает работу с многопоточным кодом, то для работы со scope-ами используйте ThreadLocal контейнер.

Критерии оценки:
1. Интерфейс IoC устойчив к изменению требований.
Оценка: 0 - 3 балла (0 - совсем не устойчив, 3 - преподаватель не смог построить ни одного контрпримера)
2. IoC предоставляет ровно один метод для всех операций - 1 балл
3. IoC предоставляет работу со scope-ами для предотвращения сильной связности - 2 балла.
4. Реализованы модульные тесты - 2 балла
5. Реализованы многопоточные тесты - 2 балла

Пример IoC контейнера:
https://github.com/etyumentcev/appserver/tree/main/appserver

Scope = context

*/
public class HW05 {
private static final Logger logger = LoggerFactory.getLogger(HW05.class);

public static void main(String[] args) {
logger.info(
"Java version: {}, Java vendor: {}\nДомашнее задание: Реализация IoC контейнера",
System.getProperty("java.version"),
System.getProperty("java.vendor"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ru.otus.main_patterns.hw05.commands;

import ru.otus.main_patterns.hw05.interfaces.Command;

public class ClearCurrentScopeCommand implements Command {

@Override
public void execute() {
InitCommand.currentScopeThreadLocal.remove();
}
}
Loading
Loading