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 首先我们来面 ...
随机推荐
- 计算字符串和文件的MD5值
//计算字符串的MD5值 public string GetMD5(string sDataIn) { MD5CryptoServiceProvider md5 = new MD5CryptoServ ...
- 几个 JavaScript 奇技淫巧
#1使用双等号给布尔变量赋值,很容易联想到 var a = b || 123; 的写法 var a = b == 123;#2快速转换为布尔值 !!a#3防止页面被 iframe 调用 if(top ...
- zzuli oj 1167逆转数(指针专题)
Description 任意给你一个整数,这个数可能很大(最长不超过100位),你能求出它的逆转数吗? 逆转数定义如下: 1.一个末尾没有0的整数,它的逆转数就是各位数字逆序输出: 2.一个负数 ...
- 【转】.Net程序员玩转Android系列之三~快速上手
原文:http://www.cnblogs.com/HouZhiHouJueBlogs/p/3962122.html 快速环境搭建和Hello World 第一步:JAVA SDK(JDK)的安装: ...
- ABAP打开TCODE
CALL FUNCTION 'TH_CREATE_MODE' EXPORTING transaktion = 'ZGNBWD001' EXCEPTIONS max_session ...
- uva 12097 - Pie
简单题,二分就行: #include<cstdio> #include<cmath> #define pi acos(-1.0) #define eps 0.000001 #d ...
- csu 10月 月赛 B 题 Scoop water
一个卡特兰数的应用: 卡特兰数主要有以下几个用途: 1.不同的出栈入栈数: 2.n个点组成的不同的二叉树的数目: 3.凸多边形的三角剖分划分: 4.括号化问题: 通项公式是:h(n) = C(2n-2 ...
- Discuz!X3.1 全新安装图文教程
http://www.discuz.net/thread-3456887-1-1.html
- 配置PhpStorm调试PHP
配置PhpStorm调试PHP 第一步:配置 XDebug 下载安装XDebug到本地环境(参考:Zend Studio 9.x + xampp + XDebug 调试环境安装详解),打开php.in ...
- Hibernate 注解 动态插入( DynamicInsert) 动态更新(DynamicUpdate)
@DynamicUpdate(value = true)@DynamicInsert(value = true) 这两个注解默认是false,经试验,如果使用了这两个注解,在一定程度上是可以提高插入和 ...