java - OOP - 一个类(class)如何变成另一个类(class)?

标签 java oop domain-driven-design

一个人有一个ID。 学生有学生证。 司机有驾照。

  • 一个人上学并成为学生。
  • 一名学生毕业并成为普通人。
  • 一个人获得驾驶执照并成为一名司机。
  • 学生获得驾照并成为司机。

那些东西只是像下面例子中的状态变化吗:

class Person {
    ID id;
    StudentID stId;
    DriverLicense license;

    void drive() {
        if(license == null) //illegal state exception
        //drive
    }

    //bla bla
}

还是有继承?由于一个对象是数据+行为,新数据和能够做新事情应该保证一个新对象

class Student extends Person {
    //
}

class Driver extends Person {
    //
}

//things get messy here, in Java you can't extend multiple class
//what if there's a rule that, student drivers can request/get a tax reduction?
class DriverStudent extends Person, Driver {
    //
}

另外,更重要的是,一个如何成为另一个?通过方法或构造函数或第 3 类(如服务或聚合)?

class Person {
    Driver getADriversLicense() {
        //create and return a Driver
        //this person still exists but now there's a driver with this person's data
    }
}

or:

class Driver extends Person {
    public Driver(Person p) {
        //constructor
    }
}

or:

class Aggregate {
    Driver giveDriversLicense(Person p) {
        // access internal state of both objects(ditch encapsulation) and return a driver?
        // put aggregate in same package with Driver and Person and use package private methods to provide encapsulation?
    }
}

最佳答案

查看这种关系的更好方法是通过角色,即一个人可以扮演多个角色。

一个人可以是司机和学生,也可以是员工的场景怎么样?

所以 IMO 最好的表示如下 -

class Person{

     List<Role> currentRoles ; 

     List<Role> getCurrentRoles(){ 
         return currentRoles ; 
     }

     public void addRole(Role role){
          currentRoles.add(role) ; // so on
     }  
}

使用泛型和类型安全转换,您可以轻松检索特定角色并对其调用相关操作。

public interface DriverRole implements Role {

    License getDriversLicense() ;
} 

编辑:进一步全面回答您的问题,它很容易解决人员获得或失去角色的情况,即添加或删除角色。正如此处的评论中所指出的,这种关系最好通过具有 <0..M> 关系然后是 IS - 一种关系来表示。

编辑 1 相比之下,当您使用装饰器模式时,您的来源会被包裹起来,过多的装饰器会创建一个聚合链,这在我看来不是一个理想的场景,否则它会导致装饰器继承链这不是我喜欢的。

话虽如此,根据特定场景,一种特定模式可能比另一种模式更适合,但在您给出的示例中,我认为角色的简单聚合是最好的。

关于java - OOP - 一个类(class)如何变成另一个类(class)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35343783/

相关文章:

java - Try & Catch 中的语法错误

java - 强连通分量

python:表示包裹自身的方形网格(圆柱体)

domain-driven-design - DDD建模,聚合根之间的交互

java - Android Rect.intersect() 不工作/没有被使用,对吧?

java - ImageButton 无法转换为 android.widget.Edittext

java - 有人可以指导我如何获取玩家对象并将其移动到二维平铺对象数组中吗?

oop - 逻辑设计与物理设计

microservices - DDD 中的编排 Sagas - 集成事件链?

c# - 使用域驱动设计将根与 Entity Framework 聚合