一个简单的菜单管理,我却迷茫了,求解惑
程序员文章站
2022-07-03 08:34:15
...
一、需求
做一个简单的CMS,关于菜单部分的需求。
系统管理员输入账号密码登陆后台系统后,首页面显示布局为:顶部水平显示一行导航菜单,左边栏显示树形菜单,点击不同的导航菜单,左边栏显示不同的树形菜单。中间是工作区。
系统管理员在导航菜单中点击菜单管理,左边栏显示:
导航菜单
|——所有导航菜单
|——添加导航菜单
树形菜单
|——所有树形菜单
|——添加树形菜单
点击添加树形菜单,工作区弹出添加页面,从上到下要求包括:
所属导航菜单(点击下拉列表,必填)
父菜单(点击下来列表,可以不选表示没有父菜单)
菜单名(必填,必须中文,2-8字,不能与现有树形菜单同名)
url(必填)
排序(整数型,必填)
提交后,要验证导航菜单和父菜单是否存在。
其他更详细的描述略之。
二、需求分析(场景在前面有描述,下面有所省略,主要围绕添加树形菜单)
1.业务建模
(a)业务用例:管理菜单
2.用例分析
用例:管理菜单
业务活动:添加树形菜单,修改树形菜单,删除树形菜单,查询所有树形菜单,查询所有导航菜单,根据菜单名查询导航菜单,根据菜单名查询树形菜单
3.系统建模
用例:把上者的业务活动的节点作为一个系统用例
用例关系:菜单管理include(添加树形菜单include(查询所有导航菜单,查询所有树形菜单,根据名字查询导航菜单,根据名字查询树形菜单))
系统架构:B/S,REST,MVC...
系统范围:...
...
三、概要设计
1.领域模型:导航菜单,树形菜单
2.包+类:
menu
|—controller
| |—TreeMenuController.class
|—service
| |—MenuManager.class
|—dao
| |—TreeMenuDAO.class
| |—NavMenuDAO.class
|—entity
|—TreeMenu.class
|—NavMenu.class
PS:1.原谅我用贫血模型 2.po和dto几乎一样,用entity算了
3.领域类:NavMenu,TreeMenu
4.领域类关系:NavMenu(1) —关联— (n)TreeMenu 树形菜单中 父菜单(1) —父子— (n)子菜单
5.类图:...
...
四、困惑
说困惑之前说说我的想法。
1.因为TreeMenu需要依赖NavMenu,所以模块划分的时候,抽象一个层次为Menu
2.同样考虑,抽象为MenuManager来做服务接口。
3.MenuManager依赖DAO接口,不依赖具体实现,具体实现类通过外部框架进行注入,从代码层面上解耦。
困惑来了。
1.采取的是贫血模型,如果我要用充血模型,请问怎么做?我尝试过,可是感觉失败了。我自己的做法是:
menu
|—application
| |—TreeMenuController.class
| |—TreeMenuVO
| |—NavMenuVO
| |—NavMenuService.class
| |—TreeMenuService.class
| |—impl
| |—TreeMenuServiceImpl.class
| |—NavMenuServiceImpl.class
|—domain
| |—NavMenu.class
| |—NavMenuRepository.class
| |—TreeMenu.class
| |—TreeMenuRepository.class
|—infrastructure
|—NavMenuDAO.class
|—TreeMenuDAO.class
|—NavMenuPO.class
|—TreeMenuPO.class
|—TreeMenuAssembler.class
|—NavMenuAssembler.class
|—impl
|—NavMenuDAOImpl.class
|—TreeMenuDAOImpl.class
几点说明:TreeMenuVO、NavMenuVO是DTO,TreeMenuPO、NavMenuPO是持久化对象,他们都由TreeMenuAssembler和NavMenuAssembler负责组装,po数据从数据库查出来,然后将数据装配到domain里,最后继续装配到vo里。反之亦然。
依赖关系:controller——>service——>repository——>dao
这么下来后感觉怪怪的,多了好多类,不知道这样算不算DDD。算不算领域模型驱动。囧。望朋友能够指正。
2.对于TreeMenuService来说,它有个操作,添加树形菜单,需要去查询获取所有的导航菜单,那么这个查询操作属于NavMenuService的职责吗?当然,它一定属于NavMenuDomainObject的。假设它也属于NavMenuService的方法,那么我想问,TreeMenuServie可以调用NavMenuService的方法吗?或者我是否改抽象出一个MenuService来?
补充:service主要作为事务边界和代理domain面向用户的接口,在其内部非简单代理domain的逻辑方法里,负责对多个domain的操作逻辑。而domain内部也有逻辑,但是这种逻辑仅与当前所在domain实例有关,不能与多个domain有关,如果是多个有关的话,应该要封装在service中。
系统的dao,service都要面向接口编程,由外部框架进行依赖的注入。
系统应该是按模块来进行包的组织。模块之间不能有任何的依赖,只能依赖公共组件。任何模块单独拿出来都能独立运行。
前面说的menu就是一个模块。
做一个简单的CMS,关于菜单部分的需求。
系统管理员输入账号密码登陆后台系统后,首页面显示布局为:顶部水平显示一行导航菜单,左边栏显示树形菜单,点击不同的导航菜单,左边栏显示不同的树形菜单。中间是工作区。
系统管理员在导航菜单中点击菜单管理,左边栏显示:
导航菜单
|——所有导航菜单
|——添加导航菜单
树形菜单
|——所有树形菜单
|——添加树形菜单
点击添加树形菜单,工作区弹出添加页面,从上到下要求包括:
所属导航菜单(点击下拉列表,必填)
父菜单(点击下来列表,可以不选表示没有父菜单)
菜单名(必填,必须中文,2-8字,不能与现有树形菜单同名)
url(必填)
排序(整数型,必填)
提交后,要验证导航菜单和父菜单是否存在。
其他更详细的描述略之。
二、需求分析(场景在前面有描述,下面有所省略,主要围绕添加树形菜单)
1.业务建模
(a)业务用例:管理菜单
2.用例分析
用例:管理菜单
业务活动:添加树形菜单,修改树形菜单,删除树形菜单,查询所有树形菜单,查询所有导航菜单,根据菜单名查询导航菜单,根据菜单名查询树形菜单
3.系统建模
用例:把上者的业务活动的节点作为一个系统用例
用例关系:菜单管理include(添加树形菜单include(查询所有导航菜单,查询所有树形菜单,根据名字查询导航菜单,根据名字查询树形菜单))
系统架构:B/S,REST,MVC...
系统范围:...
...
三、概要设计
1.领域模型:导航菜单,树形菜单
2.包+类:
menu
|—controller
| |—TreeMenuController.class
|—service
| |—MenuManager.class
|—dao
| |—TreeMenuDAO.class
| |—NavMenuDAO.class
|—entity
|—TreeMenu.class
|—NavMenu.class
PS:1.原谅我用贫血模型 2.po和dto几乎一样,用entity算了
3.领域类:NavMenu,TreeMenu
4.领域类关系:NavMenu(1) —关联— (n)TreeMenu 树形菜单中 父菜单(1) —父子— (n)子菜单
5.类图:...
...
四、困惑
说困惑之前说说我的想法。
1.因为TreeMenu需要依赖NavMenu,所以模块划分的时候,抽象一个层次为Menu
2.同样考虑,抽象为MenuManager来做服务接口。
3.MenuManager依赖DAO接口,不依赖具体实现,具体实现类通过外部框架进行注入,从代码层面上解耦。
困惑来了。
1.采取的是贫血模型,如果我要用充血模型,请问怎么做?我尝试过,可是感觉失败了。我自己的做法是:
menu
|—application
| |—TreeMenuController.class
| |—TreeMenuVO
| |—NavMenuVO
| |—NavMenuService.class
| |—TreeMenuService.class
| |—impl
| |—TreeMenuServiceImpl.class
| |—NavMenuServiceImpl.class
|—domain
| |—NavMenu.class
| |—NavMenuRepository.class
| |—TreeMenu.class
| |—TreeMenuRepository.class
|—infrastructure
|—NavMenuDAO.class
|—TreeMenuDAO.class
|—NavMenuPO.class
|—TreeMenuPO.class
|—TreeMenuAssembler.class
|—NavMenuAssembler.class
|—impl
|—NavMenuDAOImpl.class
|—TreeMenuDAOImpl.class
几点说明:TreeMenuVO、NavMenuVO是DTO,TreeMenuPO、NavMenuPO是持久化对象,他们都由TreeMenuAssembler和NavMenuAssembler负责组装,po数据从数据库查出来,然后将数据装配到domain里,最后继续装配到vo里。反之亦然。
依赖关系:controller——>service——>repository——>dao
这么下来后感觉怪怪的,多了好多类,不知道这样算不算DDD。算不算领域模型驱动。囧。望朋友能够指正。
2.对于TreeMenuService来说,它有个操作,添加树形菜单,需要去查询获取所有的导航菜单,那么这个查询操作属于NavMenuService的职责吗?当然,它一定属于NavMenuDomainObject的。假设它也属于NavMenuService的方法,那么我想问,TreeMenuServie可以调用NavMenuService的方法吗?或者我是否改抽象出一个MenuService来?
补充:service主要作为事务边界和代理domain面向用户的接口,在其内部非简单代理domain的逻辑方法里,负责对多个domain的操作逻辑。而domain内部也有逻辑,但是这种逻辑仅与当前所在domain实例有关,不能与多个domain有关,如果是多个有关的话,应该要封装在service中。
系统的dao,service都要面向接口编程,由外部框架进行依赖的注入。
系统应该是按模块来进行包的组织。模块之间不能有任何的依赖,只能依赖公共组件。任何模块单独拿出来都能独立运行。
前面说的menu就是一个模块。
推荐阅读