ApacheIsis是DDD方法的一个实现框架。
宠物诊所需要记录宠物的资料,包括类型、名字、及其主人。
多个宠物可能同属于一个主人。
宠物可能更换主人。
宠物主人记录姓名,我们可以按姓名来查找宠物主人。
根据需求,我们可以创建宠物(Pet)和宠物主人(Owner)两个实体类。宠物和主人是一对多的关系。宠物可以变更主人,当然这里我仅限于宠物来选择主人,那给宠物换主人就是宠物自身的一个行为。
创建宠物和创建宠物主人,我们需要相应业务对象来进行初始化操作。这个业务对象可以认为是一个工厂,专门用来创建不存在的实体对象。
宠物主人的查询,我们也是通过业务对象来进行实体的检索。这个业务对象可认为是一个实体仓库,我们从中检索需要的实体对象。
通过以上描述,我们建立以下的UML图形。
宠物诊所静态模型
注:由于业务规则相当简单,为了简化编程步骤,这里的宠物主人的查询和创建放到了一个类中。
将宠物主人的业务对象定义为DomainService,表明此对象宠物主人操作的入口。DomainService.repositoryFor()表明,这个类也是Owner的实体仓库。Owners在系统中对应一个菜单。
@DomainService(repositoryFor=Owner.class)publicclassOwners{//....}给这个类创建两个动作(方法),一个是创建宠物主人(Owner),另一个是用名字来查询。create方法对应创建这个动作,在界面上对应一个Create的菜单项。create参数对应创建动作要输入的内容,在界面上表现为一个输入表单。findByName同理,不过create和findByName的区别是返回不一样,前者返回所创建实体的内容(详情页),后者返回查询的实体集合(列表页)。
@MemberOrder(sequence="2")publicOwnercreate(final@ParameterLayout(named="Name")Stringname){finalOwnerobj=repository.instantiate(Owner.class);obj.setName(name);repository.persist(obj);returnobj;}//endregion//region>findByName(action)@MemberOrder(sequence="1")publicList
同样先定义Service。
@DomainService(repositoryFor=Pet.class)publicclassPets{//...}再创建Action
publicPetcreate(final@ParameterLayout(named="宠物名字")Stringname,final@ParameterLayout(named="宠物类型")PetSpeciesspecies,@ParameterLayout(named="宠物主人")finalOwnerowner){finalPetpet=repository.instantiate(Pet.class);pet.setName(name);pet.setSpecies(species);pet.setOwner(owner);repository.persist(pet);returnpet;}Pet的Action
publicPetchangeOwner(Ownerowner){setOwner(owner);returnthis;}一些扩展设计对于宠物主人的选择,为了达到与相应实体类的完全匹配,更多的时候考虑采用下拉选择。ISIS提供了一些协定,比如choice,autoComplete前辍的动作,辅助数据项的选择。
publicList
publicList