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
14 changes: 14 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,18 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.4.5</version>
</dependency>
</dependencies>

</project>
11 changes: 11 additions & 0 deletions src/main/java/strategy/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package strategy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}
14 changes: 14 additions & 0 deletions src/main/java/strategy/annotation/SupportAttackType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package strategy.annotation;

import strategy.enums.AttackType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SupportAttackType {
AttackType value();
}
7 changes: 7 additions & 0 deletions src/main/java/strategy/constant/AttackTypeValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package strategy.constant;

public class AttackTypeValue {
public static final int PHYSIC_ATTACK_VALUE = 1;
public static final int MAGIC_ATTACK_VALUE = 2;
public static final int POISON_ATTACK_VALUE = 3;
}
55 changes: 55 additions & 0 deletions src/main/java/strategy/controller/AttackController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package strategy.controller;

import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import strategy.annotation.SupportAttackType;
import strategy.enums.AttackType;
import strategy.service.AttackService;
import strategy.service.DefaultAttack;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
public class AttackController {
private Map<AttackType, AttackService> attackServiceMap;

@Autowired
private DefaultAttack defaultAttackService;

// @Autowired
// private List<AttackService> attackServices;

@GetMapping("/attack/{type}")
public String attack(@PathVariable(value = "type") int type) {
AttackType attackType = AttackType.typeOf(type);
AttackService attackService = attackServiceMap.getOrDefault(attackType, defaultAttackService);
return attackService.attack();
}

@Autowired
private void setAttackServiceMap(List<AttackService> attackServiceList) {
this.attackServiceMap = attackServiceList.stream()
.filter(attackService -> attackService.getClass().isAnnotationPresent(SupportAttackType.class))
.collect(Collectors.toMap(AttackService::getAttackTypeByService, Function.identity()));
if (this.attackServiceMap.size() != AttackType.values().length) {
throw new IllegalArgumentException("some attack types are not supported");
}
}

//The following code completes the same task as setAttackServiceMap(List)
/*@PostConstruct
private void initAttackServiceMap() {
this.attackServiceMap = attackServices.stream()
.filter(attackService -> attackService.getClass().isAnnotationPresent(SupportAttackType.class))
.collect(Collectors.toMap(AttackService::getAttackTypeByService, Function.identity()));
if (this.attackServiceMap.size() != AttackType.values().length) {
throw new IllegalArgumentException("some attack types are not supported");
}
}*/
}
26 changes: 26 additions & 0 deletions src/main/java/strategy/enums/AttackType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package strategy.enums;

import java.util.Arrays;
import java.util.function.IntPredicate;

import static strategy.constant.AttackTypeValue.*;

public enum AttackType {
PhysicalAttack(attackType -> attackType == PHYSIC_ATTACK_VALUE),
MagicAttack(attackType -> attackType == MAGIC_ATTACK_VALUE),
PoisonAttack(attackType -> attackType == POISON_ATTACK_VALUE),
;

private final IntPredicate route;

AttackType(IntPredicate route) {
this.route = route;
}

public static AttackType typeOf(int attackType) {
return Arrays.stream(values())
.filter(value -> value.route.test(attackType))
.findFirst()
.orElse(null);
}
}
17 changes: 17 additions & 0 deletions src/main/java/strategy/service/AttackService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package strategy.service;

import strategy.annotation.SupportAttackType;
import strategy.enums.AttackType;

public interface AttackService {

String attack();

default AttackType getAttackTypeByService() {
SupportAttackType annotation = this.getClass().getAnnotation(SupportAttackType.class);
if (annotation != null) {
return annotation.value();
}
throw new IllegalStateException("AttackService implementation must be annotated with @SupportAttackType");
}
}
11 changes: 11 additions & 0 deletions src/main/java/strategy/service/DefaultAttack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package strategy.service;

import org.springframework.stereotype.Service;

@Service
public class DefaultAttack implements AttackService {
@Override
public String attack() {
return "No Attack";
}
}
15 changes: 15 additions & 0 deletions src/main/java/strategy/service/MagicAttack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package strategy.service;

import org.springframework.stereotype.Service;
import strategy.annotation.SupportAttackType;
import strategy.enums.AttackType;

@Service
@SupportAttackType(AttackType.MagicAttack)
public class MagicAttack implements AttackService {
@Override
public String attack() {
System.out.println("Magic Attack");
return "Magic Attack";
}
}
15 changes: 15 additions & 0 deletions src/main/java/strategy/service/PhysicalAttack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package strategy.service;

import org.springframework.stereotype.Service;
import strategy.annotation.SupportAttackType;
import strategy.enums.AttackType;

@Service
@SupportAttackType(AttackType.PhysicalAttack)
public class PhysicalAttack implements AttackService {
@Override
public String attack() {
System.out.println("Physical Attack");
return "Physical Attack";
}
}
15 changes: 15 additions & 0 deletions src/main/java/strategy/service/PoisonAttack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package strategy.service;

import org.springframework.stereotype.Service;
import strategy.annotation.SupportAttackType;
import strategy.enums.AttackType;

@Service
@SupportAttackType(value = AttackType.PoisonAttack)
public class PoisonAttack implements AttackService {
@Override
public String attack() {
System.out.println("Poison Attack");
return "Poison Attack";
}
}
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
spring.application.name=JavaDesignPatterns