美文网首页
从UML角度理解依赖

从UML角度理解依赖

作者: 心彻 | 来源:发表于2018-07-08 17:38 被阅读21次

    什么是依赖

    简单的理解就是,一个类A用到了另一个类B,这种使用关系是具有偶然性的,临时性的,非常弱的,但是当类B发生变化时,又会影响到类A。
    举个例子:


    图1

    我们有一个Customer的Controller,它需要完成对Customer的查找或新增,如果我们用EF进行数据库操作的话,CustomerController就会对数据库的Context有一个依赖的关系。

    显式依赖与隐式依赖

    要解释这个的话,还是看代码比较直接。

    [Route("customer")]
    public class CustomerController:Controller
    {
        [HttpPost]
        [Route("add")]
        public IActionResult Add([FromBody]Model.Customer customer)
        {
            if(!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var context=new CustomerContext(new DBContextOptions<CustomerContext>{});
            var result=context.Customers.SingleOrDefault(c=>c.Phone=customer.Phone);
            if(result!=null)
            {
                return BadRequest(new {code=1001,message="手机号码已存在"});
            }
            context.Customers.Add(customer);
            context.SaveChanges();
            return Ok();
        }
    
        [HttpGet]
        [Route("detail")]
        public IActionResult Detail(int id)
        {
            var context=new CustomerContext(new DBContextOptions<CustomerContext>{});
            var customer=context.Customers.SingleOrDefault(c=>c.Id=id);
            if(result==null)
            {
                return NotFound();
            }
            return Json(customer);
        }
    }
    

    这种代码编写方式是隐式依赖。
    再来看:

    [Route("customer")]
    public class CustomerController:Controller
    {
        private CustomerContext _context;
        public CustomerController()
        {
            _context=new CustomerContext(new DBContextOptions<CustomerContext>{});
        }
    
        [HttpPost]
        [Route("add")]
        public IActionResult Add([FromBody]Model.Customer customer)
        {
            if(!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var result=_context.Customers.SingleOrDefault(c=>c.Phone=customer.Phone);
            if(result!=null)
            {
                return BadRequest(new {code=1001,message="手机号码已存在"});
            }
            context.Customers.Add(customer);
            context.SaveChanges();
            return Ok();
        }
    
        [HttpGet]
        [Route("detail")]
        public IActionResult Detail(int id)
        {
            var customer=_context.Customers.SingleOrDefault(c=>c.Id=id);
            if(result==null)
            {
                return NotFound();
            }
            return Json(customer);
        }
    }
    

    这种就是显式依赖。

    依赖倒置

    高层业务不依赖于低层业务的具体实现,而依赖于具体的抽象。上面的UML图可以修改如下:


    图2

    将来,如果不适用EF,而改用其他方式的话,UML图可改动如下:


    图3

    这就实现了依赖倒置,具体代码如下:

    [Route("customer")]
    public class CustomerController:Controller
    {
        private ICustomerRepository _customerRepository;
        public CustomerController()
        {
            _customerRepository=new EFCustomerRepository(new DBContextOptions<CustomerContext>{});
        }
    
        [HttpPost]
        [Route("add")]
        public IActionResult Add([FromBody]Model.Customer customer)
        {
            if(!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var result=_customerRepository.GetPhone(customer.Phone);
            if(result!=null)
            {
                return BadRequest(new {code=1001,message="手机号码已存在"});
            }
            _customerRepository.Insert(customer);
            return Ok();
        }
    
        [HttpGet]
        [Route("detail")]
        public IActionResult Detail(int id)
        {
            var customer=_customerRepository.GetById(id);
            if(result==null)
            {
                return NotFound();
            }
            return Json(customer);
        }
    }
    

    控制反转

    将控制权交出去,代码如下:

        private ICustomerRepository _customerRepository;
        public CustomerController(ICustomerRepository customerRepository)
        {
            _customerRepository=customerRepository;
        }
    

    这样,你既可以传EFCustomerRepository,也可以传MemoryCustomerRepository了。

    相关文章

      网友评论

          本文标题:从UML角度理解依赖

          本文链接:https://www.haomeiwen.com/subject/zauouftx.html