Asp.Net Design Pattern Studynotes -- Part1
Asp.Net Design Pattern Studynotes -- Part1
let's start with an exampleto entry amazing OO world !
let's saynow we need to implement a small feature which need :
an entityclass: Product
businesslogic : List<Product>GetProductBy(Function<Product,bool> where);
Service : List<Product> GetProductBy(Function<Product,bool>where);
1st Version
Entity:
public classProduct{}
Logic:
public classProductRepositoryV1
{ public List<Product>GetProductBy(Func<Product,bool> where )
{
var products = newList<Product>();
returnproducts.Where(where).ToList();
}
}
service:
classProductServiceV1
{
private ProductRepositoryV1 _productRespository;
private List<Product>_cacheProduct ; public ProductServiceV1()
{
_productRespository = newProductRepositoryV1(); //1.instant
_cacheProduct = newList<Product>();
} public List<Product>GetProductListBy(Func<Product,bool> where)
{
var productInCache =_cacheProduct.Where(where);//3.in couple with BL
if (!productInCache.Any())
{
var products =_productRespository.GetProductBy(where);
_cacheProduct.AddRange(products); //2.also care about how to cache
return products;
}
return productInCache.ToList();
} }
But we cansee the deficiencies :
For 1stVersion (Original Version):
1.productServiceis in couple with ProductRepository .once productRespository changed method signature, service have to change code.
solution: depend onabstract but not on concrete implementation
2.code is untestable .which need data base ready , but if data base can not connect ,meaning can not be tested.
solution: decoupleservice from business class
3.do multiple things .
a. cache thedata ,b. provice service .c. instance the repository object .
solution : do only one thing .
ok, nowlet's fix it !
2nd version :
Entity: same with above .
business:
interface IProductRespository//added interface fordependency inversion
{
List<Product>GetProductBy(Func<Product, bool> where);
}
class ProductRespositoryV2:IProductRespository
{
public List<Product>GetProductBy(Func<Product, bool> where)
{
var products = newList<Product>();
returnproducts.Where(where).ToList();
}
}
Service :
class ProductServiceV2
{
private IProductRespository _productRespository;
private List<Product>_cacheProduct ; public ProductServiceV2(IProductRespositorypr)
{
_productRespository = pr;
_cacheProduct = newList<Product>();
} public List<Product> GetProductListBy(Func<Product,bool> where)
{
var productInCache =_cacheProduct.Where(where);
if (!productInCache.Any())
{
var products =_productRespository.GetProductBy(where);
_cacheProduct.AddRange(products);
return products;
}
return productInCache.ToList();
}
}
For 2ndVersion (Applydependency inversion + Dependency injection):
.still do multiple things:
a.still need to care about how to store . b. provide service
solution :put the responsibility of cache storage into another class,let service only depends on interface (IStorage)
3rd Version(Adapter pattern + Dependency inversion)
Entity :same with above .
business:
interface IProductRespository
{
List<Product> GetProductBy(Func<Product, bool> where);
}
interface IStorage
{
void Add(IEnumerable<Product>products);
IEnumerable<Product> Get(Func<Product, bool> where);
} class MemoryStorage:IStorage // Take the responsibility ofCache
{
private List<Product>_cacheProduct;
public MemoryStorage()
{
_cacheProduct = newList<Product>();
}
public void Add(IEnumerable<Product> products)
{
_cacheProduct.AddRange(products);
} public IEnumerable<Product> Get(Func<Product, bool> where)
{
return _cacheProduct.Where(where);
}
} class ProductRespositoryV3:IProductRespository
{
public List<Product> GetProductBy(Func<Product, bool> where)
{
var products = new List<Product>();
return products.Where(where).ToList();
}
}
Service:
class ProductServiceV3
{
// only dependson abstract
private IProductRespository_productRespository;
private IStorage_cache; public ProductServiceV3(IProductRespository pr, IStorage storage)
{
//new objalso do not care
_productRespository = pr;
_cache = storage;
}
public List<Product> GetProductListBy(Func<Product,bool> where)
{
var productInCache = _cache.Get(where);
if (!productInCache.Any())
{
var products = _productRespository.GetProductBy(where);
_cache.Add(products);
return products;
}
return productInCache.ToList();
}
}
We Can see ,
1.Service only depends on Interface which is abstract(no more need to care about how to cache the data) ,
2.and for Service, storage and respository class only do one thing
3.for service ,respository ,storage all can be UT .
Whenever weare coding any class,always remember these 3 things :
1.only do one thing
2.depends only on abstract
3.always can be tested
Asp.Net Design Pattern Studynotes -- Part1的更多相关文章
- Thinking In Design Pattern——MVP模式演绎
原文<Thinking In Design Pattern——MVP模式演绎>不知为何丢失了,故重新整理了一遍. 目录 What Is MVP Domain Model StubRepos ...
- 说说设计模式~大话目录(Design Pattern)
回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...
- 设计模式(Design Pattern)系列之.NET专题
最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...
- [转]Design Pattern Interview Questions - Part 4
Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...
- [转]Design Pattern Interview Questions - Part 2
Interpeter , Iterator , Mediator , Memento and Observer design patterns. (I) what is Interpreter pat ...
- [转]Design Pattern Interview Questions - Part 3
State, Stratergy, Visitor Adapter and fly weight design pattern from interview perspective. (I) Can ...
- [转]Design Pattern Interview Questions - Part 1
Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...
- design pattern
1. visitor design pattern http://butunclebob.com/ArticleS.UncleBob.IuseVisitor
- Design Pattern: Observer Pattern
1. Brief 一直对Observer Pattern和Pub/Sub Pattern有所混淆,下面打算通过这两篇Blog来梳理这两种模式.若有纰漏请大家指正. 2. Use Case 首先我们来面 ...
随机推荐
- 文件操作 系统备份和还原,压缩,解压 tar dump/restore
基本操作命令: ls -a 显示指定目录下的目录和文件,包括隐藏的文件和目录 ls -l 将文件和目录详细列出来,包括文件状态,权限,拥有者,文件名,文件大小等 改变工作目录命令 cd cd .. 进 ...
- MySQL在远程访问时非常慢的解决skip-name-resolve 并且出现 Reading from net
转载:http://www.itokit.com/2012/0515/73932.html 服务器放在局域网内进行测试时,数据库的访问速度还是很快.但当服务器放到外网后,数据库的访问速度就变得非常慢. ...
- PHP下拉框选择的实现方法
实现 第一种PHP下拉框实现方法: < ?php //提交下拉框; //直接饱触发onchange事件的结果 $id=$_GET['myselect']; // myselect 为locati ...
- ARM编译器4字节对齐
(1)我们假设只有一个赋初值的char型全局变量,那么系统会在data区分配一个4字节的存储空间来存储它.实际上,只用了1个字节,但是为了4字节对齐,只好分配4个字节,所以就会有3个字节浪费. (2) ...
- C# 使用Salt+Hash来为密码加密
(一) 为什么要用哈希函数来加密密码 如果你需要保存密码(比如网站用户的密码),你要考虑如何保护这些密码数据,象下面那样直接将密码写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到 ...
- django入门教程(上)
相信用过python的人都听过Django的大名,知道它是一个web框架,用来支持动态网站.网络应用程序以及网络服务的开发.那么为什么我们需要一个web框架,而不是直接用python来写web应用呢? ...
- Android-x86虚拟机安装配置全攻略
转自Android-x86虚拟机安装配置全攻略 注:这里安装从简,具体请参考虚拟机Vmware安装运行安卓4.0详细教程 Android-x86虚拟机安装配置网上有很多,但是全部说明白的确不多,希望这 ...
- PYTHON不定参数与__DOC__
def total(initial = 5, *numbers, **keywords): count = initial for number in numbers: count += number ...
- CENTOS6上禁用IPV6和DHCP
centos 6禁用ipv6方法 首先,在终端输入 ip -6 addr show 和 lsmod | grep ipv6查询一下有无安装IPV6模块,或用netstat -nuptl查看是否有i ...
- Highcharts实例
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...