從UML角度理解依賴

什么是依賴

簡單的理解就是,一個(gè)類A用到了另一個(gè)類B,這種使用關(guān)系是具有偶然性的,臨時(shí)性的,非常弱的,但是當(dāng)類B發(fā)生變化時(shí),又會影響到類A。
舉個(gè)例子:


圖1

我們有一個(gè)Customer的Controller,它需要完成對Customer的查找或新增,如果我們用EF進(jìn)行數(shù)據(jù)庫操作的話,CustomerController就會對數(shù)據(jù)庫的Context有一個(gè)依賴的關(guān)系。

顯式依賴與隱式依賴

要解釋這個(gè)的話,還是看代碼比較直接。

[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="手機(jī)號碼已存在"});
        }
        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="手機(jī)號碼已存在"});
        }
        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);
    }
}

這種就是顯式依賴。

依賴倒置

高層業(yè)務(wù)不依賴于低層業(yè)務(wù)的具體實(shí)現(xiàn),而依賴于具體的抽象。上面的UML圖可以修改如下:


圖2

將來,如果不適用EF,而改用其他方式的話,UML圖可改動如下:


圖3

這就實(shí)現(xiàn)了依賴倒置,具體代碼如下:

[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="手機(jī)號碼已存在"});
        }
        _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);
    }
}

控制反轉(zhuǎn)

將控制權(quán)交出去,代碼如下:

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

這樣,你既可以傳EFCustomerRepository,也可以傳MemoryCustomerRepository了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容