设计模式二:工厂模式

Posted .NET开发菜鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式二:工厂模式相关的知识,希望对你有一定的参考价值。

  这是我们用得比较多的一种设计模式,也是23种标准设计模式之一,使用前面讲的简单工厂设计模式,遇到具体产品经常变换时就不太适合了,违反了开闭设计原则;怎么才能避免修改工厂类呢?工厂方法模式可以做到。
  工厂方法模式要求我们应该有一个抽象的工厂类,我们知道尽量使用抽象类或接口来定义就可以达到一个开闭原则的效果,这样我们在抽象的工厂类定义一个生产产品的方法,这个方法就是工厂方法,这也是工厂方法模式的由来,他具体的行为会有他的子类或实现类来实现。如果想生产某种产品,就定义一个新的产品,新的产品工厂类,这样就实现了不同的产品进行一个不同的创建,这样如果有信的产品,只需要添加新的工厂类,原来写好的代码不会发生变化,这种方式符合开闭原则,可扩展比较好。 

添加一个具体产品,只需要在添加一个具体产品的工厂类实现抽象工厂类,不需要修改原来的代码

 

示例代码:

抽象产品类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /*
10        动物抽象类
11      * 抽象产品
12      */
13     public abstract class Animal
14     {
15         public abstract void Eat();
16     }
17 }

抽象工厂类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /*
10       动物抽象工厂类
11      
12      */
13     public abstract class AnimalFactory
14     {
15         public abstract Animal GetAnimal();
16 
17     }
18 }

生产狗的具体工厂类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 具体工厂:生成狗
11     /// </summary>
12    public class DogFactory :AnimalFactory
13     {
14 
15         public override Animal GetAnimal()
16         {
17             return new Dog();
18         }
19     }
20 }

生产企鹅的具体工厂类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 具体工厂:生成企鹅
11     /// </summary>
12     public class PenguinFactory :AnimalFactory
13     {
14         public override Animal GetAnimal()
15         {
16             return new Penguin();
17         }
18     }
19 }
View Code

具体产品狗类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /*
10        具体的产品类,实现抽象产品类
11      */
12     public class Dog:Animal
13     {
14         // 实现抽象方法
15         public override void Eat()
16         {
17             Console.WriteLine("狗在吃饭!");
18         }
19     }
20 }
View Code

具体产品企鹅类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /*
10       具体产品类,实现抽象产品类
11      
12      */
13     public class Penguin : Animal
14     {
15         // 实现抽象方法
16         public override void Eat()
17         {
18             Console.WriteLine("企鹅在吃饭!");
19         }
20     }
21 }
View Code

客户端调用:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             AnimalEat(new  DogFactory());
14             Console.ReadKey();
15         }
16 
17         static void AnimalEat(AnimalFactory af)
18         {
19             Animal am = af.GetAnimal();
20             am.Eat();
21         }
22     }
23 }
View Code

类图:

如果想在增加一个Cat类,只需要增加一个具体的Cat类实现Animal类的方法,增加一个具体的Cat工厂类实现抽象工厂类即可,不需要在修改已经写好的代码,符合开闭原则。

使用接口的方式实现工厂模式

需求:使用面向对象的方式设计一个系统,描述使用卡车从事货运,使用公共汽车从事客运。使用工厂模式实现。

1、汽车接口:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 汽车接口
11     /// </summary>
12     public interface ICar
13     {
14         /// <summary>
15         /// 描述汽车从事的活动
16         /// </summary>
17         void Work();
18     }
19 }

2、分别定义卡车(Truck)和公共汽车(Bus)类实现汽车接口(ICar)里面的Work()方法

Truck类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 卡车类
11     /// </summary>
12     public class Truck : ICar
13     {
14         /// <summary>
15         /// 卡车从事的活动
16         /// </summary>
17         public void Work()
18         {
19             Console.WriteLine("卡车从事货运");
20         }
21     }
22 }

Bus类:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 公共汽车类
11     /// </summary>
12     public class Bus:ICar
13     {
14         /// <summary>
15         /// 公共汽车从事的活动
16         /// </summary>
17         public void Work()
18         {
19             Console.WriteLine("公共汽车从事客运");
20         }
21     }
22 }

3、定义汽车的工厂接口(ICarFactory):

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 汽车工厂接口
11     /// </summary>
12     public interface ICarFactory
13     {
14          ICar GetCar();
15     }
16 }

4、分别定义卡车工厂(TruckFactory)和公共汽车工厂(BusFactory)实现ICarFactory接口

TruckFactory工厂:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 卡车工厂接口
11     /// </summary>
12     public class TruckFactory:ICarFactory
13     {
14         /// <summary>
15         /// 返回卡车类
16         /// </summary>
17         /// <returns></returns>
18         public ICar GetCar()
19         {
20             return new  Truck();
21         }
22     }
23 }

BusFactory工厂:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     /// <summary>
10     /// 公共汽车工厂
11     /// </summary>
12     public class BusFactory:ICarFactory
13     {
14         /// <summary>
15         /// 返回公共汽车类
16         /// </summary>
17         /// <returns></returns>
18         public ICar GetCar()
19         {
20             return new  Bus();
21         }
22     }
23 }

5、主程序调用:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 工厂模式
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13           
14             CarWork(new TruckFactory());
15             Console.ReadKey();
16         }
17 
18 
19         /// <summary>
20         /// 根据汽车工厂返回具体的汽车类
21         /// </summary>
22         /// <param name="cf"></param>
23         static void CarWork(ICarFactory cf)
24         {
25             ICar c = cf.GetCar();
26             c.Work();
27         }
28     }
29 }

6、程序运行结果

 代码连接地址:http://files.cnblogs.com/files/dotnet261010/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.rar

以上是关于设计模式二:工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

PHP面向对象之选择工厂和更新工厂

设计模式学习——简单工厂模式工厂模式抽象工厂模式

设计模式工厂方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

C#设计模式之二工厂方法模式(Factory Method Pattern)创建型

案例分析:设计模式与代码的结构特性

设计模式之工厂模式