[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 02 业务逻辑层
2011-01-31 23:00
1061 查看
注:本例来自图书Professional ASP.NET Design Pattern,该书的亚马逊链接为:http://www.amazon.com/Professional-ASP-NET-Design-Patterns-Millett/dp/0470292784/ref=sr_1_1?ie=UTF8&qid=1296479229&sr=8-1
转载请注明本文来自博客园 http://www.cnblogs.com/charrli
业务逻辑层就是将数据的获取和数据的表现同数据的“转换方法"(业务逻辑)分离出来,单独进行建模,成为数据访问层和数据表现层的中间层。这里我们要实现的业务逻辑如前文所说:
显示在ASPX页面上,该表如下:
这里程序试图实现的业务逻辑为:当用户选择不打折(no discount)时,售价Selling Price与数据库相同;当用户选择打折时,SellingPrice为原价95折。如果最终的SellingPrice比RRP建议零售价低,则在Discount里显示折扣了多少,同时在Savings栏里显示折扣比例。如果SellingPrice比RRP价格高或者相等,则Discount和Savings都不显示。
对业务逻辑建模如下:
这里Product类是对表Product建模得到,Price代表了表中几个与借个相关的属性。同时表明,Price中有一个field是IDiscountStrategy接口对象。该接口有两个实现,一是NullDiscountStrategy,二是TradeDiscountStrategy。下面介绍对业务逻辑层Business Logic Layer的实现步骤。注意最好是把每个类都使用一个单独的CS文件。
1. 实现IDiscountStrategy接口:
public interface IDiscountStrategy
{
decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice);
}
这里接口以Strategy命名结尾,表明这里才采用了策略模式Strategy Pattern。所谓策略模式,就是让对象在运行时动态改变自己的算法和行为。在这个例子里,策略模式表现为,对象需要根据客户选择NoDiscount还是TradeDiscount来改变Selling Price的价格。具体实现上,这里使用的方法是,在Price内部有一个接口对象,它可以指向一个NullDiscountStrategy对象,也可以指向一个TradeDiscountStrategy对象,而这两个对象都有自己的不同的价格的实现方法。
2. 实现TradeDiscountStrategy类:
public class TradeDiscountStrategy : IDiscountStrategy
{
public decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice)
{
decimal price = OriginalSalePrice;
price = price * 0.95M;
return price;
}
}
3. 实现NullDiscountStrategy类:
public class NullDiscountStrategy : IDiscountStrategy
{
public decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice)
{
return OriginalSalePrice;
}
}
4. 实现Price类:
public class Price
{
private IDiscountStrategy _discountStrategy = new NullDiscountStrategy();
private decimal _rrp;
private decimal _sellingPrice;
public Price(decimal RRP, decimal SellingPrice)
{
_rrp = RRP;
_sellingPrice = SellingPrice;
}
public void SetDiscountStrategyTo(IDiscountStrategy DiscountStrategy)
{
_discountStrategy = DiscountStrategy;
}
public decimal SellingPrice
{
get { return _discountStrategy.ApplyExtraDiscountsTo(_sellingPrice); }
}
public decimal RRP
{
get { return _rrp; }
}
public decimal Discount
{
get {
if (RRP > SellingPrice)
return (RRP - SellingPrice);
else
return 0;}
}
public decimal Savings
{
get{
if (RRP > SellingPrice)
return 1 - (SellingPrice / RRP);
else
return 0;}
}
}
注意这里Price类将原数据库中的表的两个与价格相关的field全部实现为了Private的field,也就是说外部不能直接访问,如果要访问呢,必须要铜鼓Price类的Property才可以。这样就给程序使用get;set;方法,利用动态的Strategy来对价格进行变换提供了机会。
这里private的RRP和SellingPrice的值只能在构造函数中直接赋值,所以这两个field的值始终与数据库里的相同。
同时注意到SetDiscountStrategy方法,这给外部操作Price类提供了一机会,可以直接修改Property获得的价格的Strategy。
5. 实现Product类:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public Price Price { get; set; }
}
6. 实现CustomType枚举类型:
public enum CustomerType
{
Standard = 0,
Trade = 1
}
这里Standard代表没有折扣,Trade代表有折扣。
7. 实现DiscountFactory类:
public static class DiscountFactory
{
public static IDiscountStrategy GetDiscountStrategyFor(CustomerType customerType)
{
switch (customerType)
{
case CustomerType.Trade:
return new TradeDiscountStrategy();
default:
return new NullDiscountStrategy();
}
}
}
这里用到了工厂模式。所谓工厂模式,就是静态类(表明该类即不能继承也不能实例,专为用作使用其内部的静态方法)内部得静态方法,可以利用一个switch结构,根据不同的输入参数,产生不同的对象。
8. 实现IProductRepository接口:
public interface IProductRepository
{
IList<Product> FindAll();
}
这里用到了仓储模式。所谓仓储模式,就是将数据库中的数据抽象为内存中的代表,从而实现了上层应用与数据库具体内容的分离。
9. 实现ProductListExtensionMethods类:
public static class ProductListExtensionMethods
{
public static void Apply(this IList<Product> products, IDiscountStrategy discountStrategy)
{
foreach (Product p in products)
{
p.Price.SetDiscountStrategyTo(discountStrategy);
}
}
}
这里使用到了拓展方法。使用拓展方法可以将要对对象使用的方法,变成对象自己拥有的方法。因为如果是要对该对象使用该方法,那么需要一个动作的发出者,但是我们显然不知道谁发出这个动作比较好,所以将这个对对象实施的方法,变成了对象自己拥有的方法。注意这里“对象”不仅仅是指已经由类所定义的对象,还包括IList这样的泛型接口。
10. 实现Product Service类:
public class ProductService
{
private IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public IList<Product> GetAllProductsFor(CustomerType customerType)
{
IDiscountStrategy discountStrategy = DiscountFactory.GetDiscountStrategyFor(customerType);
IList<Product> products = _productRepository.FindAll();
products.Apply(discountStrategy);
return products;
}
}
ProductService类的作用就是,根据上层传入的CustomerType,返回本类中定义的Product的集合。
在以上十个文件都完成以后,由于使用了接口实现了层与层之间的断耦,该Project可以独立进行build。
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 01 准备工作
/article/6133832.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 02 业务逻辑层
/article/6133833.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 03 服务层
/article/6133834.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 04 数据访问层
/article/6133835.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 05 表现层
/article/6133836.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 06 用户界面层
/article/6133837.html
转载请注明本文来自博客园 http://www.cnblogs.com/charrli
业务逻辑层就是将数据的获取和数据的表现同数据的“转换方法"(业务逻辑)分离出来,单独进行建模,成为数据访问层和数据表现层的中间层。这里我们要实现的业务逻辑如前文所说:
显示在ASPX页面上,该表如下:
这里程序试图实现的业务逻辑为:当用户选择不打折(no discount)时,售价Selling Price与数据库相同;当用户选择打折时,SellingPrice为原价95折。如果最终的SellingPrice比RRP建议零售价低,则在Discount里显示折扣了多少,同时在Savings栏里显示折扣比例。如果SellingPrice比RRP价格高或者相等,则Discount和Savings都不显示。
对业务逻辑建模如下:
这里Product类是对表Product建模得到,Price代表了表中几个与借个相关的属性。同时表明,Price中有一个field是IDiscountStrategy接口对象。该接口有两个实现,一是NullDiscountStrategy,二是TradeDiscountStrategy。下面介绍对业务逻辑层Business Logic Layer的实现步骤。注意最好是把每个类都使用一个单独的CS文件。
1. 实现IDiscountStrategy接口:
public interface IDiscountStrategy
{
decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice);
}
这里接口以Strategy命名结尾,表明这里才采用了策略模式Strategy Pattern。所谓策略模式,就是让对象在运行时动态改变自己的算法和行为。在这个例子里,策略模式表现为,对象需要根据客户选择NoDiscount还是TradeDiscount来改变Selling Price的价格。具体实现上,这里使用的方法是,在Price内部有一个接口对象,它可以指向一个NullDiscountStrategy对象,也可以指向一个TradeDiscountStrategy对象,而这两个对象都有自己的不同的价格的实现方法。
2. 实现TradeDiscountStrategy类:
public class TradeDiscountStrategy : IDiscountStrategy
{
public decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice)
{
decimal price = OriginalSalePrice;
price = price * 0.95M;
return price;
}
}
3. 实现NullDiscountStrategy类:
public class NullDiscountStrategy : IDiscountStrategy
{
public decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice)
{
return OriginalSalePrice;
}
}
4. 实现Price类:
public class Price
{
private IDiscountStrategy _discountStrategy = new NullDiscountStrategy();
private decimal _rrp;
private decimal _sellingPrice;
public Price(decimal RRP, decimal SellingPrice)
{
_rrp = RRP;
_sellingPrice = SellingPrice;
}
public void SetDiscountStrategyTo(IDiscountStrategy DiscountStrategy)
{
_discountStrategy = DiscountStrategy;
}
public decimal SellingPrice
{
get { return _discountStrategy.ApplyExtraDiscountsTo(_sellingPrice); }
}
public decimal RRP
{
get { return _rrp; }
}
public decimal Discount
{
get {
if (RRP > SellingPrice)
return (RRP - SellingPrice);
else
return 0;}
}
public decimal Savings
{
get{
if (RRP > SellingPrice)
return 1 - (SellingPrice / RRP);
else
return 0;}
}
}
注意这里Price类将原数据库中的表的两个与价格相关的field全部实现为了Private的field,也就是说外部不能直接访问,如果要访问呢,必须要铜鼓Price类的Property才可以。这样就给程序使用get;set;方法,利用动态的Strategy来对价格进行变换提供了机会。
这里private的RRP和SellingPrice的值只能在构造函数中直接赋值,所以这两个field的值始终与数据库里的相同。
同时注意到SetDiscountStrategy方法,这给外部操作Price类提供了一机会,可以直接修改Property获得的价格的Strategy。
5. 实现Product类:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public Price Price { get; set; }
}
6. 实现CustomType枚举类型:
public enum CustomerType
{
Standard = 0,
Trade = 1
}
这里Standard代表没有折扣,Trade代表有折扣。
7. 实现DiscountFactory类:
public static class DiscountFactory
{
public static IDiscountStrategy GetDiscountStrategyFor(CustomerType customerType)
{
switch (customerType)
{
case CustomerType.Trade:
return new TradeDiscountStrategy();
default:
return new NullDiscountStrategy();
}
}
}
这里用到了工厂模式。所谓工厂模式,就是静态类(表明该类即不能继承也不能实例,专为用作使用其内部的静态方法)内部得静态方法,可以利用一个switch结构,根据不同的输入参数,产生不同的对象。
8. 实现IProductRepository接口:
public interface IProductRepository
{
IList<Product> FindAll();
}
这里用到了仓储模式。所谓仓储模式,就是将数据库中的数据抽象为内存中的代表,从而实现了上层应用与数据库具体内容的分离。
9. 实现ProductListExtensionMethods类:
public static class ProductListExtensionMethods
{
public static void Apply(this IList<Product> products, IDiscountStrategy discountStrategy)
{
foreach (Product p in products)
{
p.Price.SetDiscountStrategyTo(discountStrategy);
}
}
}
这里使用到了拓展方法。使用拓展方法可以将要对对象使用的方法,变成对象自己拥有的方法。因为如果是要对该对象使用该方法,那么需要一个动作的发出者,但是我们显然不知道谁发出这个动作比较好,所以将这个对对象实施的方法,变成了对象自己拥有的方法。注意这里“对象”不仅仅是指已经由类所定义的对象,还包括IList这样的泛型接口。
10. 实现Product Service类:
public class ProductService
{
private IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public IList<Product> GetAllProductsFor(CustomerType customerType)
{
IDiscountStrategy discountStrategy = DiscountFactory.GetDiscountStrategyFor(customerType);
IList<Product> products = _productRepository.FindAll();
products.Apply(discountStrategy);
return products;
}
}
ProductService类的作用就是,根据上层传入的CustomerType,返回本类中定义的Product的集合。
在以上十个文件都完成以后,由于使用了接口实现了层与层之间的断耦,该Project可以独立进行build。
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 01 准备工作
/article/6133832.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 02 业务逻辑层
/article/6133833.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 03 服务层
/article/6133834.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 04 数据访问层
/article/6133835.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 05 表现层
/article/6133836.html
[ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 06 用户界面层
/article/6133837.html
相关文章推荐
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 06 用户界面层
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 03 服务层
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 04 数据访问层
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 01 准备工作
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的分层结构示例Step by Step —— 05 表现层
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的WCF分层结构示例Step by Step —— 02 Model的建立
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的WCF分层结构示例Step by Step —— 04 DataContract
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的WCF分层结构示例Step by Step —— 05 Contracts
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的WCF分层结构示例Step by Step —— 03 数据访问层
- [ASP.NET 设计模式] 用Visual Studio2010搭建一个简单的WCF分层结构示例Step by Step —— 01 准备工作
- ASP.NET组件设计Step by Step(7)
- 经验技巧分享--ASP.NET和Ajax应用一个超级实用的设计模式---享元模式
- Scott Mitchell 的ASP.NET 2.0数据教程之二:创建一个业务逻辑层
- ASP.NET组件设计Step by Step(6)
- ASP.NET组件设计Step by Step(7)
- 一起谈.NET技术,走向ASP.NET架构设计——第四章—业务层分层架构(中篇)
- asp.net+sqlserver实现的简单高效的权限设计示例
- 一起谈.NET技术,走向ASP.NET架构设计——第五章:业务层模式,原则,实践(前篇)
- ASP.NET MVC:示例编号mvc100010010,一个简单MVC示例
- ASP.NET组件设计Step by Step(8)