设计模式之抽象工厂模式(一)

系统 1679 0

  一、模式描述

 我的程序中有需要一系列的对象,比如我们要吃一碗米饭(Rice),要喝一杯咖啡(Coffee)......,要想利用他们,我们就必须在程序中根据用户要求,然后一个个调用 new 操作符来生成他们,这样客户程序就要知道相应的类的信息,生成的代码显然不够灵活。那么我们可以在代码中不利用具体的类,而只是说明我们需要什么,然后就能够得到我们想要的对象呢? 

   这当然是可以的,根据GOF在《设计模式》一书里介绍,要创建对象这样的工作应该是属于创建型模式完成的。熟悉各种设计模式意图的朋友就会很快得出结 论:“提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类”,至少“无需指定它们具体的类”符合我们的要求。OK,这就是抽象工厂模式 的意图。

  二、模式意图

  提供一个创建一系列相关或相互依赖对象的接口,而不需指定他们具体的类。

  三、模式UML图:         

解读设计模式----抽象工厂模式(AbstractFactory Pattern)

  四、模式参与者

解读设计模式----抽象工厂模式(AbstractFactory Pattern) 抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。

解读设计模式----抽象工厂模式(AbstractFactory Pattern) 具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。

解读设计模式----抽象工厂模式(AbstractFactory Pattern) 抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。

解读设计模式----抽象工厂模式(AbstractFactory Pattern) 具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

  五、模式与反射

 利用设计模式可以使我们的代码更灵活,更容易扩展,更容易维护。各种面向对象的程序设计语言都提供了基本相同的机制:比如类、继承、派生、多态等等。但是又有各自的特色,C# 中的反射机制便是一个很重要的工具,好好地利用就可以在实际中发挥很大的作用。

 反射是.NET Framework中的一个非常重要的特性。相信绝大多数的朋友都对其有所了解或是已经熟练的应用这项技术。 我们需要根据需求去动态的创建一对象的实例,在程序设计中,通常我们会为了解耦合,把接口的实现对象写入配置文件,让工厂自己去一个特定的地方(配置文 件)找他应该要实例化的对象(接口的实现对象),通过这样来实现“依赖注入(Dependency Injection)”。

  本来“依赖注入”需要专门的IOC容器提供,比如Spring.net,Castle这类似的框架产品。而在抽象工厂模式的应用中显然没有这么麻烦,通常的实现就是使用.NET技术‘反射’就可以了。下面是反射的两种常见应用:

 应用一:

  Activator.CreateInstance("类型");

  应用二:

  Assembly.Load("程序集名称").CreateInstance("命名空间.类名称");

  六、抽象工厂的简单实现

  Entity Code

1namespace DesignPattern.AbstractFactory
2{
3  public class User
4  {
5    private int _id;
6    public int Id
7    {
8      get { return _id; }
9      set { _id = value; }
10    }
11
12    private string _name;
13    public string Name
14    {
15      get { return _name; }
16      set { _name = value; }
17    }
18
19    private string _age;
20    public string Age
21    {
22      get { return _age; }
23      set { _age = value; }
24    }
25
26    public User()
27    { }
28
29    public User(int id, string name, string age)
30    {
31      _id = id;
32      _name = name;
33      _age = age;
34    }
35  }
36}
37----------------------------------------------------------------------
38namespace DesignPattern.AbstractFactory
39{
40  public class News
41  {
42    private int _id;
43    public int Id
44    {
45      get { return _id; }
46      set { _id = value; }
47    }
48
49    private string _title;
50    public string Title
51    {
52      get { return _title; }
53      set { _title = value; }
54    }
55
56    private string _context;
57    public string Context
58    {
59      get { return _context; }
60      set { _context = value; }
61    }
62
63    private string _author;
64    public string Author
65    {
66      get { return _author; }
67      set { _author = value; }
68    }
69
70    public News()
71    { }
72
73    public News(int id, string title, string context, string author)
74    {
75      _id = id;
76      _title = title;
77      _context = context;
78      _author = author;
79    }
80  }
81}
82

1namespace DesignPattern.AbstractFactory
2{
3  /**//// <summary>
4  /// 抽象产品角色
5  /// </summary>
6  public interface INews
7  {
8    void Insert(News news);
9    News QueryById(int newsId);
10  }
11
12  /**//// <summary>
13  /// 具体产品角色
14  /// </summary>
15  public class NewsSql:INews
16  {
17    public void Insert(News news)
18    {
19      Console.WriteLine("插入新闻到SQL数据库");
20    }
21
22    public News QueryById(int newsId)
23    {
24      return new News(1, "Hello", " Hello C#!", "beniao");
25    }
26  }
27
28  /**//// <summary>
29  /// 具体产品角色
30  /// </summary>
31  public class NewsAccess : INews
32  {
33    public void Insert(News news)
34    {
35      Console.WriteLine("插入新闻到Access数据库");
36    }
37
38    public News QueryById(int newsId)
39    {
40      return new News(1, "Hello", " Hello C#!", "beniao");
41    }
42  }
43}

1namespace DesignPattern.AbstractFactory
2{
3  /**//// <summary>
4  /// 抽象产品角色
5  /// </summary>
6  public interface IUser
7  {
8    void Insert(User user);
9    User QueryById(int userId);
10  }
11
12  /**//// <summary>
13  /// 具体产品角色
14  /// </summary>
15  public class UserSql:IUser
16  {
17    public void Insert(User user)
18    {
19      Console.WriteLine("Insert SQL OK!");
20    }
21
22    public User QueryById(int userId)
23    {
24      return new User(1, "beniao", "22");
25    }
26  }
27
28  /**//// <summary>
29  /// 具体产品角色
30  /// </summary>
31  public class UserAccess : IUser
32  {
33    public void Insert(User user)
34    {
35      Console.WriteLine("Insert Access OK!");
36    }
37
38    public User QueryById(int userId)
39    {
40      return new User(2, "beniao", "23");
41    }
42  }
43}

1namespace DesignPattern.AbstractFactory
2{
3  /**//// <summary>
4  /// 工厂角色(根据配置文件来确定创建何种对象)
5  /// </summary>
6  public class DataAccess
7  {
8    public static IUser CreateUser()
9    {
10      string obj = ConfigurationManager.AppSettings["usersql"];
11      return (IUser)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
12    }
13
14    public static INews CreateNews()
15    {
16      string obj = ConfigurationManager.AppSettings["newssql"];
17      return (INews)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
18    }
19  }
20***********************************************************************************
21  /**//// <summary>
22  /// 如果根据GOF的定义及UML图,此为抽象工厂角色
23  /// </summary>
24  public class Factory
25  {
26    public virtual IUser CreateUser()
27    {
28      return null;
29    }
30
31    public virtual INews CreateNews()
32    {
33      return null;
34    }
35  }
36
37  /**//// <summary>
38  /// 具体的工厂角色
39  /// </summary>
40  public class SqlFactory:Factory
41  {
42    public override IUser CreateUser()
43    {
44      string obj = ConfigurationManager.AppSettings["usersql"];
45      return (IUser)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
46    }
47
48    public override INews CreateNews()
49    {
50      string obj = ConfigurationManager.AppSettings["newssql"];
51      return (INews)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
52    }
53  }
54
55  /**//// <summary>
56  /// 具体的工厂角色
57  /// </summary>
58  public class AccessFactory : Factory
59  {
60    public override IUser CreateUser()
61    {
62      string obj = ConfigurationManager.AppSettings["useracc"];
63      return (IUser)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
64    }
65
66    public override INews CreateNews()
67    {
68      string obj = ConfigurationManager.AppSettings["newsacc"];
69      return (INews)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
70    }
71  }
72}

1namespace DesignPattern.AbstractFactory
2{
3  class Program
4  {
5    static void Main(string[] args)
6    {
7      IUser user = DataAccess.CreateUser();
8      user.Insert(null);
9
10      INews news = DataAccess.CreateNews();
11      news.Insert(null);
12
13      //******************GOF************************
14
15      Factory factory = new SqlFactory();
16      factory.CreateNews().Insert(null);
17      factory.CreateUser().Insert(null);
18
19      factory = new AccessFactory();
20      factory.CreateNews().Insert(null);
21      factory.CreateUser().Insert(null);
22    }
23  }
24}

设计模式之抽象工厂模式(一)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论