因为渴求进步,所以分享我所理解的设计模式。同时也为了抛砖引玉,因为你我都需要成长!
客户需求1:请为我们电子商务网站的电子类产品计算价格,并打印显示出来.可能出现的一个实现版本代码如下:
View Code
1 public class MP4 2 { 3 public MP4() 4 { 5 Name = "MP4"; 6 Price = 260; 7 } 8 9 public String Name 10 { 11 set; 12 get; 13 } 14 public Double Price 15 { 16 set; 17 get; 18 } 19 20 public void Print() 21 { 22 System.Console.WriteLine("商品{0} 价格:{1}", Name, Price); 23 } 24 }
View Code
1 public class Pad 2 { 3 public Pad() 4 { 5 Name = "Pad"; 6 Price = 3800; 7 } 8 9 public String Name 10 { 11 set; 12 get; 13 } 14 public Double Price 15 { 16 set; 17 get; 18 } 19 20 public void Print() 21 { 22 System.Console.WriteLine("商品{0} 价格:{1}", Name, Price); 23 } 24 }
View Code
1 public class Phone 2 { 3 public Phone() 4 { 5 Name = "Phone"; 6 Price = 4200; 7 } 8 9 public String Name 10 { 11 set; 12 get; 13 } 14 public Double Price 15 { 16 set; 17 get; 18 } 19 20 public void Print() 21 { 22 System.Console.WriteLine("商品{0} 价格:{1}", Name, Price); 23 } 24 }
然后客户程序代码可能这样调用:
View Code
1 static void Main(string[] args) 2 { 3 MP4 mp4 = new MP4(); 4 Pad pad = new Pad(); 5 Phone phone = new Phone(); 6 mp4.Print(); 7 pad.Print(); 8 phone.Print(); 9 }
大家说这样实现有问题么?如果说客户需求是一尘不变的,价格也不会变,商品种类也不会增加,这样的实现是没有问题的,因为需求永远不会变。可实际生活中需求是一直在变化.
客户需求2:在节日期间,我们所有的商品的都打对折,且增加笔记本商品来销售。
需求变化了,缺乏工作经验的人可能会这样处理:打开类MP4把里边的价格260 * 0.5,再增加一个类Computer,然后编译发布程序。请问这样做可以么?可以,因为它的确解决了我们的问题。但是不妨我们这样想一想以后如果需求还要变化,且很频繁,那么我们岂不是要不停的这样做重复的工作,这样不仅不利于系统的维护也不利于自己的成长.而且这样改变有许多风险.首先,我们改变了本不需要改变的功能代码(返回价格函数),还好这里只是返回一个简单的价格,如果里边包含了大量的业务逻辑判断那可麻烦了,更改时还要看懂业务逻辑。其次,如果这样的类有几十上百个甚至更多该怎么办,难道也要一个一个找出来改?如果改漏掉怎么办?再其次,如果我们以前的程序代码已经部署在公司好多电脑上,可能还要考虑接口的兼容性,以及请测试人员测试我们的代码功能。我们仅仅是改了一个不算复杂的功能,就要改动这么多东西,真是牵一发而动全身啊.那么怎样设计才能让我们避免此类问题出现,可以让我们的系统具有灵活性、可扩展、易维护、可复用,易阅读,才能更好适应需求的变化。
这里给出我的第一个版本设计,整理后的的完整代码如下:
View Code
1 public abstract class Goods 2 { 3 public Goods() 4 { 5 Init(); 6 } 7 public String Name 8 { 9 set; 10 get; 11 } 12 public Double Price 13 { 14 set; 15 get; 16 } 17 public IStrategy DisCountsStrategy 18 { 19 get; 20 set; 21 } 22 public void Print() 23 { 24 System.Console.WriteLine("商品{0} 价格:{1}", Name, Price * DisCountsStrategy.DisCounts); 25 } 26 protected abstract void Init(); 27 }
View Code
1 public class GoodsFactory : IGoodsFactory 2 { 3 Goods IGoodsFactory.MakeMP4() 4 { 5 return new MP4(); 6 } 7 8 Goods IGoodsFactory.MakePad() 9 { 10 return new Pad(); 11 } 12 13 Goods IGoodsFactory.MakePhone() 14 { 15 return new Phone(); 16 } 17 }
View Code
1 public class GoodsStore : IStore 2 { 3 private IGoodsFactory goodsFactory; 4 5 public GoodsStore(IGoodsFactory goodsFactory) 6 { 7 this.goodsFactory = goodsFactory; 8 } 9 10 IEnumerator IStore.CreateGoods() 11 { 12 IList<Goods> goodsList = new List<Goods>(); 13 Goods mp4 = goodsFactory.MakeMP4(); 14 Goods pad = goodsFactory.MakePad(); 15 Goods phone = goodsFactory.MakePhone(); 16 goodsList.Add(mp4); 17 goodsList.Add(pad); 18 goodsList.Add(phone); 19 return goodsList.GetEnumerator(); 20 } 21 22 void IStore.Print(IEnumerator ienumerator) 23 { 24 while (ienumerator.MoveNext()) 25 { 26 Goods goods = ienumerator.Current as Goods; 27 goods.Print(); 28 } 29 } 30 }
View Code
1 public class HalfPercentStrategy : IStrategy 2 { 3 Double IStrategy.DisCounts 4 { 5 get { return 0.5; } 6 } 7 }
View Code
1 public interface IGoodsFactory 2 { 3 Goods MakeMP4(); 4 Goods MakePad(); 5 Goods MakePhone(); 6 }
View Code
1 public interface IStore 2 { 3 IEnumerator CreateGoods(); 4 void Print(IEnumerator ienumerator); 5 }
View Code
public interface IStrategy { Double DisCounts { get; } }
View Code
1 public class MP4 : Goods 2 { 3 protected override void Init() 4 { 5 Name = "MP4"; 6 Price = 260; 7 DisCountsStrategy = new HalfPercentStrategy(); 8 } 9 }
View Code
1 public class OnePercentStrategy : IStrategy 2 { 3 Double IStrategy.DisCounts 4 { 5 get { return 1; } 6 } 7 }
View Code
1 public class Pad : Goods 2 { 3 protected override void Init() 4 { 5 Name = "Pad"; 6 Price = 2600; 7 DisCountsStrategy = new OnePercentStrategy(); 8 } 9 }
View Code
1 protected override void Init() 2 { 3 Name = "Phone"; 4 Price = 4000; 5 DisCountsStrategy = new HalfPercentStrategy(); 6 }
客户代码调用:
View Code
1 static void Main(string[] args) 2 { 3 IStore store = new GoodsStore(new GoodsFactory()); 4 IEnumerator items = store.CreateGoods(); 5 store.Print(items); 6 }
分类: 设计模式