【问题标题】:factory like pattern with spring bean without switch case带弹簧豆的工厂样图案,不带开关盒
【发布时间】:2019-02-15 03:18:14
【问题描述】:

我的目标是根据枚举返回一个方法。目前,我创建了一个工厂,但它使用的是我不喜欢的开关盒。代码运行良好,但我想使用更好的模式并替换当前的开关盒。如果没有任何开关盒或 if else (instance of),您将如何设计它...

我还尝试在枚举中实现 Stategy 模式。但是自动装配 bean 是不可能的。

请看下面我当前的一段代码。

public enum Car {
     AUDI, FORD;
}
public class SuperCar{
     private Car car;
}
public class Audi extends SuperCar{
     // some other properties
}
public class Ford extends SuperCar{
     // some other properties
}
@Service
public class AudiService{

     public void save(Audi audi){
         // some code
     }

}
@Service
public class FordService{

     public void save(Ford ford){
         // some code
     }

}
@Service
public class CarFactory{

     private FordService fordService;
     private AudiService audiService;

     public CarFactory(FordService fordService, AudiService audiService) {
           this.fordService = fordService;
           this.audiService = AudiService;     
     }

     public void saveCar(SuperCar superCar){
         switch(superCar.getCar()):
             case AUDI:
                 return audiService.save((Audi)superCar));
             case FORD:
                 return fordService.save((Ford)superCar));
             default:
                 return null;

     }

}

感谢您的帮助。

【问题讨论】:

  • switch 有什么问题?你说的更好是什么意思?您使用什么标准?
  • 我不喜欢使用 switch,因为当其他开发人员添加新枚举时,他通常会忘记实现所有 switch 模式。我使用它们,但最好避免使用它们
  • 没有解决这个问题的模式。我建议您创建通过Car.values() 迭代的测试并调用您的工厂方法。
  • 您可以只抛出一个异常,说明不支持新添加的枚举以知道您的工厂中缺少代码行
  • 我已经这样做了。我只是想改进我的代码并使用所有开关盒。但我期待这个答案。我已经在互联网上到处搜索了。

标签: java spring switch-statement case factory


【解决方案1】:

如果只是替换 switch,我总是更喜欢使用 map 的更具声明性的方法,因为它更易于维护和阅读:

private Map<Car, CarService> services;

public CarFactory(FordService fordService, AudiService audiService) {
   this.services = Map.of(Car.FORD, fordService, Car.AUDI, audiService);
}

public void saveCar(SuperCar superCar) {
   CarService service = services.get(superCar.getCar());
   if (service != null) service.save(..);
}

使用通用接口:

private interface CarService<T extends SuperCar> {
   void save(T car);
}

无论如何,我会重新考虑您的对象模型以让超级汽车自救(正如其他人已经建议的那样)。

【讨论】:

    【解决方案2】:

    很抱歉,我无法发表评论。在这里,汽车的类型决定了汽车服务。我不确定策略模式是否适合这里。当同一辆车存在不同的服务行为时,我会使用策略模式。例如:夏天我想使用 XService,而冬天我想为 AUDI 使用 YService。我看到了两种实现方式。

    1. 在创建汽车对象期间注入服务。通过这种实现,汽车与服务紧密耦合。我不建议这样做,除非您有充分的理由不遵循第 2 点。
    2. 使用 if/else 或分支来确定汽车的类型并调用所需的服务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-15
      • 2023-04-04
      • 1970-01-01
      • 2012-12-22
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      相关资源
      最近更新 更多