有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是不是一个坏模式:确定接口实现的类

我有接口

interface Car {
  enum Type { MITSUBISHI, FORD }
  Car.Type getType();

和两个实现接口的类

class Mitsubishi implements Car {
  @Override
  Car.Type getType() { return Car.Type.MITSUBISHI; }
}
class Ford implements Car {
  @Override
  Car.Type getType() { return Car.Type.FORD; }
}

并且像野外一样使用它

List<Car> cars = this.cars;
List<Mitsubishi> mitsubishiCars = cars.stream().filter(c -> c.getType().equals(Car.Type.MITSUBISHI)).collect(Collectors.toList());

问题,这是不是一个坏模式?如果是,为什么


共 (1) 个答案

  1. # 1 楼答案

    一般来说,这似乎是一个糟糕的模式,因为接口Car不应该知道谁实现了它,而包含这个enum Type会自动获取其潜在实现的知识

    也就是说,这完全取决于你如何使用Car.Type

    最可能的情况是,您希望使用枚举值来确定要执行的指定操作。例如:

    //park the car depending on the type
    switch (type) {
        case MITSUBISHI:
            //park in a certain way
        case FORD:
            //park in some other way
        //...
    }
    

    如果是这样的话,除了知道接口的实现之外,我还看到了至少两个问题:

    • 每次有一个新的Car实现时,都需要在接口Car内丰富枚举Type。这可能很烦人
    • Type的值变大时,无论是什么流结构(switchif块等)都将变得巨大且难以维护

    如果是这样的话,我宁愿在界面中创建方法,根据汽车类型处理操作。例如:

    interface Car {
        void park();
    }
    
    class Mitsubishi implements Car {
        @Override
        public void park() {
            //way to park a Mitsubishi
        }
    }
    

    如果只是想在某个点(比如在日志中)使用枚举值打印汽车类型,那么只需在界面中添加一个String getType()方法,返回正确的品牌:

    interface Car {
        String getType();
    }
    
    class Mitsubishi implements Car {
        @Override
        public String getType() {
            return "Mitsubishi";
        }
    }
    

    但总的来说,我不会建议这样的方法,除非你不想使用你不共享的Car.Type(尽管我真的不知道除了我上面列出的两种情况之外,你可能还想如何使用enum)

    后期编辑

    了解如何使用枚举后:

    List<Car> cars = this.cars;
    List<Mitsubishi> mitsubishiCars = cars.stream()
        .filter(c -> c.getType().equals(Car.Type.MITSUBISHI))
        .collect(Collectors.toList());
    

    我认为您可以在接口外部定义枚举,然后在接口中创建Type getType()方法,然后像这样使用它:

     cars.stream()
         .filter(c -> c.getType() == Type.MITSUBISHI)
         .collect(Collectors.toList());
    

    (当然,假设Mitsubishi实现将在Type getType()上返回Type.MITSUBISHI