欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个简单的菜单管理,我却迷茫了,求解惑

程序员文章站 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就是一个模块。