设计模式读书笔记之工厂方法模式
---每一模式的出现都是为了解决某一种或某一类问题,或者对某种对象间的耦合关系进行解耦合,使紧耦合变成松耦合的关系。
1.前言(解耦过程)
当我们阅读了之前的“简单工厂”那篇读书笔记之后,很多朋友都会有这样类似的一个问题就是---为什么笔记中只提到简单工厂的优点而且没有提到缺点呢? 这里将和大家一起分析简单工厂的缺点或者遗留的问题:
当我们习惯于简单工厂之后,都很喜欢把简单工厂应用到自己的项目中,比如最简单的应用就是创建数据库连接或者创建服务层接口等。我们用久了会发现一个问题就是:
我们需求是不可能一直不变的,比如就拿“简单工厂”中的水果示例来说:
我们已经有了一个苹果类、葡萄类、香蕉类,那如果客户想吃梨子呢?怎么办?
我们就马上会想到 我添加一个梨子的类就可以了,代码如下:
View Code
1 public class Pear:IFruit
2 {
3 public string Name { get; set; }
4 public string Skin { get; set; }
5
6 public void Display()
7 {
8 Console.WriteLine("我是梨子");
9 }
10 }
然后在简单工厂中添加一个创建梨子的办法,如果是参数工厂(简单工厂中的工厂,靠接收来的参数创建对象)的话, 那更好办,在方法中添加一个判断条件IF-ELSE,然后实例化下梨子的对象就可以了,那以后想要别的呢?难道一个个添加么?
简单工厂代码:
View Code
1 public class OrchardFactory
2 {
3 public IFruit ProvideApple()
4 {
5 return new Apple { Name = "苹果", Skin = "Green" };
6 }
7 public IFruit ProvideBanana()
8 {
9 return new Banana { Name = "香蕉", Skin = "Yellow" };
10 }
11 public IFruit ProvideGrape()
12 {
13 return new Grape { Name = "葡萄", Skin = "Grape" };
14 }
15
16 public IFruit ProvidePear()
17 {
18 return new Pear { Name = "梨子", Skin = "Pear" };
19 }
20 }
参数工厂代码:
View Code
1 public class ParmFactory
2 {
3 public IFruit ProvideFruit(string fruitName)
4 {
5 IFruit refFruit = null;
6
7 if ("Apple".Equals(fruitName))
8 {
9 refFruit = new Apple { Name = "苹果", Skin = "Green" };
10 }else if ("Banana".Equals(fruitName))
11 {
12 refFruit = new Banana { Name = "香蕉", Skin = "Yellow" };
13 }else if ("Grape".Equals(fruitName))
14 {
15 refFruit = new Grape { Name = "葡萄", Skin = "Grape" };
16 }else if ("Pear".Equals(fruitName))
17 {
18 refFruit = new Pear { Name = "梨子", Skin = "Pear" };
19 }
20
21 return refFruit;
22 }
23 }
从上面代码中看出,无论是简单工厂还是参数工厂他们都无法解决的问题就是每次有新产品出现的时候,它们必须做两件事:第一件是添加新产品(这里就是Pear类),第二件 是他们都会修改工厂对象里面的逻辑(添加一个创建方法或者修改方法中的判断逻辑),从上面问题中可以看出,第二件事情违背了开闭原则(对扩展开放,对修改关闭)。
我们再观察下简单工厂结构图
图1-1
从上面结构图中看到,我们简单工厂本来依赖是客户跟具体实现之间紧耦合,然后修改后变成客户依赖于工厂和水果接口,这里我们得到一个提示就是,我们应该依赖于接口,我们 就会想到一句话:“要针对接口编程,而不是针对实现编程”。我们尝试去定义一个接口,我们想到了一个办法就是,我们可以定义一个抽象(接口或者抽象类),这里为什么要定义一个这样的抽象?因为抽象对我们来说是稳定的,这样我们客户端依赖于抽象,而不是依赖于具体的工厂,每个具体工厂都实现抽象工厂中创建的产品方法。
抽象工厂接口代码如下:
View Code
1 public inte易做图ce IFactory
2 {
3 IFruit CreateFriut();
4 }
具体实现工厂代码如下:
View Code
1 /// <summary>
2 /// 苹果工厂
3 /// </summary>
4 public class AppleFactory:IFactory
5 {
6 public IFruit CreateFriut()
7 {
8 &nb
补充:Web开发 , ASP.Net ,