Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';在面向对象设计中,处理类型指示器的最佳方法是什么?_Java_Oop_Ooad_Object Oriented Analysis - Fatal编程技术网

Java 什么';在面向对象设计中,处理类型指示器的最佳方法是什么?

Java 什么';在面向对象设计中,处理类型指示器的最佳方法是什么?,java,oop,ooad,object-oriented-analysis,Java,Oop,Ooad,Object Oriented Analysis,我们的商业模式要求(比如)识别不同类型的车辆。例如,摩托车、轮船、游艇、农用设备、雪地摩托、重型卡车、轻型卡车、客车和“其他” 我认为有两种方法来处理它:创建一个包含几个子类的Vehicle类,比如boat、truck、car,并使用一个枚举来指示实际的类型。这将起作用,使您能够表示与公共子类共享一些公共特性的车辆。但它允许您使用与类不匹配的枚举 我认为处理它的传统方法是为每种类型都有一个单独的子类,它可以是车辆的子类,也可以是车辆的子类。例如,重型和轻型卡车可能是卡车的子类;船和游艇可能是船的

我们的商业模式要求(比如)识别不同类型的车辆。例如,摩托车、轮船、游艇、农用设备、雪地摩托、重型卡车、轻型卡车、客车和“其他”

我认为有两种方法来处理它:创建一个包含几个子类的Vehicle类,比如boat、truck、car,并使用一个枚举来指示实际的类型。这将起作用,使您能够表示与公共子类共享一些公共特性的车辆。但它允许您使用与类不匹配的枚举

我认为处理它的传统方法是为每种类型都有一个单独的子类,它可以是车辆的子类,也可以是车辆的子类。例如,重型和轻型卡车可能是卡车的子类;船和游艇可能是船的子类;摩托雪橇车可能是汽车的一个子类。问题是,它实际上不适合表示其他概念

有没有人对这类场景有任何模式或最佳实践

彼得

编辑: 该物体的目的是传达有关车辆的信息,并能够以用户友好的方式显示该信息。例如,从数据库中提取数据并将其显示在要查看/编辑的屏幕上

这导致了传统OO的另一个缺点,传统OO的另一个缺点是不使用实际类型的类型指示器,因为要显示类型,需要执行某种类型的实例,并将值转换为用户友好的值


(另外,我说的是单个枚举,而不是每个子类的枚举。)

我将从一个载体开始,而不是添加太多抽象。
我不会使用类层次结构来描述可以使用字段来描述的东西

这些类型的代码是否如此不同

例如,假设你有一种你以前没想到的类型。比如水上汽车(一种可以在水上行驶的汽车)或者赛维,或者独轮车。您可以为每种类型创建一个新类,也可以使用如下字段对其进行完全数据驱动

name: aqua-car
type: Exotic Car
travelsOnWater: true
travelsOdLand: true
wheels: 4

我建议你读得更好,只添加你需要的抽象,而不是你能想象的抽象。

你的问题没有简单的答案。因为它取决于您必须使用该数据结构执行的业务逻辑

我将从一个接口
Vehicle
开始,该接口将解析来自的标识符,以获得具体代表的描述

interface VehicleIdentyficator {
  String identyficator();
}

interface Vehicle {

  Identyficator getIdentyficator();

}
有了它,您就不局限于类、枚举或其他类型的设计

然后,我将使用类层次结构来描述每个车辆的属性

之后,在代码中添加一些逻辑/行为方面,并查看我的数据结构是否适用于该任务

在一天结束时,重要的方面是执行一些操作

例如,没有创建点三类卡车,轻型卡车和HavyTruck

您可以创建一个类,通过它们执行的任务来描述它们

  • 它们可以在地面上运输
  • 这辆轻型卡车可以载较少的货物,但它过去常在小城市行驶
  • 这辆重型卡车与轻型卡车相反。具有大范围承载能力
当我们把它和船比较时,我们发现船更像轻型卡车,唯一的区别是它在水上行驶

所以试着去理解这个物体,不是它是什么,而是它能做什么。it可以执行哪些任务以及限制是什么。然后你的设计将真正接近你需要的

我希望这句话是正确的,我会重复一遍。这意味着你正在使用这些交通工具,而不是建造它们。所以,专注于他们的使命,而不是他们的身体方面

但是你可以这样做

 enum VechicleType implements VehicleIdentyficator {
   TRUCK("TRUCK"),
   HEAVY_TRUCK("HEAVY_TRUCK")

   private final String indentyficator;

   private VechicleType(String indetyficator) {
     this.indentyficator = identyficator;
   }

   public String identyficator() {
       return indentyficator; 
   }

 }

但是,每次添加新车辆时,您必须覆盖将使用这种新硬编码类型的所有点

正如其他人所说,我认为这取决于你将如何使用你的车辆

  • 如果您只需要在某些点上区分类型,但大多数情况下以相同的方式处理所有车辆,请选择枚举类型

  • 如果您真的需要指定不同的行为,并使用共享的特性/行为,请使用完整的类层次结构。这也是我喜欢的方法,因为我觉得它提供了更多的进化性


  • 真正的问题

    两个“东西”需要有多大的不同才能配得上自己的阶级

    答案

    这完全取决于您将如何使用这些对象

    • 您是否会根据它们拥有的某些属性(例如,它是否浮动?)对它们进行比较?如果是这样的话,一个具有区分属性的单一类是有意义的
    • 是否要在界面上显示对象?在应用程序中,在一个表中显示轻型卡车和重型卡车是否有意义?如果它们不能有意义地存在并显示为一个数据集,那么有两个类是有意义的
    这只是两个例子。关键是,如果您创建一个新类,它应该是有用的。Java特别容易过度抽象


    如何处理
    其他

    其他听起来像是一组不是卡车也不是汽车的车辆。听起来你想抓住所有其他车辆,把它们放在一个类中。为什么不使用车辆级别?不要创建另一个从Vehicle派生的类,而是添加零功能。同样的有用性测试也适用于这里

    • 车辆
      是否足以满足我对所有“其他”车辆的需求?如果没有,我需要创建更多的类

    我接受了你的建议,创建了两个有用的类。现在,我无法区分它们,我拒绝使用instanceof。我该怎么办?

    class SpeedBoat implements VehicleInfo { public int getWheelCount() { return 0; } public boolean isTruck() { return false; } public boolean isWaterVehicle() { return true; } }
    abstract class AbstractTruck implements VehicleInfo
    {
        public final int isTruck()
        {
            return true;
        }
    }