wes*_*eyy 5 java polymorphism design-patterns visitor
我知道已经有类似的问题,但是看着它们,我仍然对应该如何设计代码有一些疑问。我有一项允许User
注册/登录/更新/删除的服务。事实是,它User
是一种抽象类型,其中包含应typeOfUser
基于其调用实际注册/更新/删除方法的数据,现在我在一个switch-case
块中进行操作。我想用一些更好的设计代替它。
UserController.java
public class UserController {
public UserDto register(UserDto user) {
switch(user.getTypeOfUser()) {
case DRIVER: return driverService.register(user);
case CUSTOMER: return customerService.register(user);
// ...
}
}
public UserDto update(UserDto user) {
switch(user.getTypeOfUser) {
case DRIVER: return driverService.update((DriverDto) user);
case CUSTOMER: return customerService.update((CustomerDto) user);
// ...
}
}
public UserDto login(long userId) {
loginService.login(userId);
UserBO user = userService.readById(userId);
switch(user.getTypeOfUser) {
case DRIVER: return DriverDto.fromBO((DriverBO) user);
case CUSTOMER: return CustomerDto.fromBO((CustomerBO) user);
// ...
}
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
据我所知,类似Visitor
模式可以被使用,但我真的需要补充的方法注册/登录/更新/删除的Enum
本身?我真的不知道如何做到这一点,感谢您的帮助。
我想用一些更好的设计代替它。
替换switch
语句并利用多态性的第一步是确保每个操作都具有单个协定(读取方法签名),而与用户类型无关。以下步骤将说明如何实现此目的:
步骤1:定义用于执行所有操作的通用接口
interface UserService {
public UserDto register(UserDto user);
public UserDto update(UserDto user);
public UserDto login(UserDto user)
}
Run Code Online (Sandbox Code Playgroud)
步骤2:让UserController将UserService当作依赖项
public class UserController {
private UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
public UserDto register(UserDto user) {
userService.register(user);
}
public UserDto update(UserDto user) {
userService.update(user);
}
public UserDto login(long userId) {
userService.login(user);
}
}
Run Code Online (Sandbox Code Playgroud)
步骤3:创建子类以处理将CustomerDto和CustomerBO作为依赖项的不同类型的用户
class CustomerService implements UserService {
private CustomerDto userDto;
private CustomerBO userBO;
public CustomerService(UserDto userDto,UserBO userBo) {
this.userDto = (CustomerDto)userDto;
this.userBO= (CustomerBO)userBo;
}
//implement register,login and update methods to operate on userDto and userBo
}
Run Code Online (Sandbox Code Playgroud)
DriverService
以类似的方式实现类,分别依赖于DriverBo
和DriverDto
对象。
步骤4:实现一个运行时工厂,该工厂决定将哪个服务传递给UserController:
public UserControllerFactory {
public static void createUserController(UserDto user) {
if(user.getTypeOfUser().equlas(CUSTOMER)) {
return new UserController(new CustomerService(user));
} else if(user.getTypeOfUser().equlas(DRIVER)) {
return new UserController(new DriverService(user));
}
}
}
Run Code Online (Sandbox Code Playgroud)
步骤5致电工厂以创建用户控制器
UserDto user = someMethodThatCreatesUserDto(();
UserController controller = UserControllerFactory.createUserController(user);
controller.register();
controller.update();
controller.login();
Run Code Online (Sandbox Code Playgroud)
上述方法的优点是将switch / if-else语句完全移回了一个类,即工厂。
你想要这样的东西:
public abstract class User {
abstract void register();
abstract void update();
abstract void login();
// maybe some more common non-abstract methods
}
Run Code Online (Sandbox Code Playgroud)
任何类型的 User 都会有一个扩展此抽象类的类,因此必须实现其所有抽象方法,如下所示:
public class Driver extends User {
public void register() {
// do whatever a driver does when register...
}
public void update() {
// do whatever a driver does when update...
}
public void login() {
// do whatever a driver does when login...
}
}
public class Customer extends User {
public void register() {
// do whatever a customer does when register...
}
public void update() {
// do whatever a customer does when update...
}
public void login() {
// do whatever a customer does when login...
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您就可以避免任何 switch case 代码。例如,您可以有一组User
s,其中每个数组都将使用new Driver()
或进行实例化new Customer()
。然后,例如,如果您迭代此数组并执行所有User
slogin()
方法,则将根据其特定类型调用每个用户的 login() ==> 不需要 switch-case,不需要转换!
归档时间: |
|
查看次数: |
3757 次 |
最近记录: |