gpt4 book ai didi

Java 策略模式 - 作为类型成员的未经检查的调用

转载 作者:行者123 更新时间:2023-11-30 06:48:00 24 4
gpt4 key购买 nike

我有一个服务,我正在做很多 if/else 语句,所以我发现使用 Strategy Pattern 可以帮到我很多。

我正在使用 Mongo,我需要在数据库中的不同集合中存储两个不同的模型。这些模型扩展了一个具有一些相似信息的共同点。我开始在运行时决定使用哪个类,但现在我的代码显示警告:unchecked call to 'save(T)' as a member of type 'Strategy'

下面是我正在尝试执行的代码。现在,我只是添加了一个 @SuppressWarnings("unchecked") 并且到目前为止它正在工作,但我想确认这是否会导致问题以及什么是更好的方法。

问题:我该如何解决这个问题?

目前的代码:

interface Strategy<T extends Person> {
T save(T model);
//other methods
}

class StudentStrategy implements Strategy<Student> {
private StudentRepository studentRepository;

public Student save(Student student) {
return studentRepository.save(student);
}
}
class TeacherStrategy implements Strategy<Teacher> {
private TeacherRepository teacherRepository;

public Teacher save(Teacher teacher) {
return teacherRepository.save(teacher);
}
}

class PersonService {
void doSomething(Person person) {
Strategy strategy = StrategyFactory.getStrategy(person.getType());
strategy.save(person); //THIS LINE SAYS A unchecked call to 'save(T)' as a member of type 'Strategy'
}
}

class StrategyFactory {
public static Strategy getStrategy(PersonType personType) {
if(personType == STUDENT) return new StudentStrategy();
if(personType == TEACHER) return new TeacherStrategy();
return null;
}
}

旧代码:

这是我之前做的代码。如您所见,有很多 if/else。更改存储库以存储 Person 不是一个选项,因为我需要每个子类的信息..

class OldPersonService {
void doSomething(Person person) {
if(person.getType == STUDENT) {
studentRepository.save(person);
} else {
teacherRepository.save(person);
}
person.setBirthday(new Date());
person.setName("john");
if(person.getType == STUDENT) {
studentRepository.findReferals(person);
} else {
teacherRepository.findReferals(person);
}
}
}

最佳答案

您的工厂返回原始 Strategy :

class StrategyFactory {
public static Strategy getStrategy(PersonType personType) {
if(personType == STUDENT) return new StudentStrategy();
if(personType == TEACHER) return new TeacherStrategy();
return null;
}
}

所以对于使用这个工厂的客户端类:

Strategy strategy = StrategyFactory.getStrategy(person.getType());
strategy.save(person);

编译器发出警告 save()是一种设计用于泛型类型的方法:

T save(T model);

在你的情况下 T应该是 StudentTeacher但你没有在工厂方法中指定它。

确保策略工厂客户端类的类型安全,getStrategy()应该返回一个符合客户期望的策略。

例如,您可以定义一个作用域方法类型:<T extends Person>你用来施放策略的:

 public static <T extends Person>  Strategy<T> getStrategy(PersonType personType) {
if(personType == STUDENT) return (Strategy<T>) new StudentStrategy();
if(personType == TEACHER) return (Strategy<T>) new TeacherStrategy();
return null;
}
}

您可以注意到 getStrategy() 中的向下转换方法。
如果您想定义一个返回 Strategy 的唯一方法,这些是不可避免的。使用根据客户端请求更改的通用类型参数化的实例。
现在,在提供程序类中执行强制转换总是比在客户端类中执行强制转换要好,在客户端类中执行强制转换应该多次执行并且可能容易出错。

这样,客户端可以写:

Strategy<Person> strategy = StrategyFactory.getStrategy(person.getType());
strategy.save(person);

关于Java 策略模式 - 作为类型成员的未经检查的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44976847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com