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 首先我们来面 ...
随机推荐
- 针对IE的CSS hack 全面 实用
.all IE{property:value\9;} .gte IE 8{property:value\0;} .lte IE 7{*property:value;} .IE 8/9{property ...
- python 三分钟入门
1.Python环境配置(2.7版本): Python官网:https://www.python.org/ Pycharm官网 http://www.jetbrains.com/pycharm/dow ...
- 网站seo优化--jsoup 批量分析相关网站 标签,描述,关键词.
网站seo优化--jsoup 批量分析相关网站 标签,描述,关键词. 因为自己写了一个磁力搜索网站Btgoogle,准备进行优化一下,需要分析其他的网站的优化情况. Java的Jsoup类库和PHP的 ...
- sitecustomize.py 用法
1.在python安装目录下的lib下的site-packages 目录中,新建文件sitecustomize.py.这是个特殊的文件,在python启动时会自动执行其中的语句.在sitecustom ...
- mysql-5.5.25-winx64在win7 x64 免安装配置
os:win7 x64 mysql:mysql-5.5.25-winx64 将mysql-5.5.25-winx64.zip 解压缩到F:\mysql-5.5.25-winx64 目录下: 1.将my ...
- 实现目标文件与源码分开的makefile测试实验
uboot提供了两种编译策略,即可以将生成的目标文件与源码混在一起,也可以将生成的目标文件与源码分开.通过对uboot Makefile的分析,笔者编写了一个简单的实现这种功能的Makfile. 顶层 ...
- 【web安全】第三弹:web攻防平台pentester安装及XSS部分答案解析
web for pentester是国外安全研究者开发的的一款渗透测试平台,通过该平台你可以了解到常见的Web漏洞检测技术. 下载链接及文档说明: http://pentesterlab.com/ex ...
- XCode 项目配置说明
初学XCode最让人头疼的就是项目各属性设置,各种不解,这里做个总结: 项目配置: 基本项(Basic) 1.Architectures(指令集)——设置你想支持的指令集,目前ios的指令集有以下几种 ...
- [置顶] Android Journal
==================================================================================================== ...
- Stanford Parser学习入门(2)-命令行运行
在Stanford parser目录中已经定义了一部分命令行工具以及图形界面,本文将介绍如何在windows使用这些工具进行语法分析,Linux下也有shell可以使用. 关于如何搭建环境请参考上一篇 ...