代码改变世界

C#设计模式——抽象工厂

2013-12-06 10:29  y-z-f  阅读(615)  评论(0编辑  收藏  举报

一、引言

           我相信看到这段文字的人,都具备了良好的技术功底。但是对于自己编写的代码总是充满抱怨,希望能够将自己编写的代码如同房子一般先进行有效

的设计,然后在进行建设。那么这篇文章能够给你一些思路,这里特别的说明只是思路,因为你可以根据实际组合改变使用这里介绍的所有设计模式,而不是

跟遵守规章一样,一丝不苟。下面我们就开始按照三种类型的设计模式进行阐述。

 

二、创建型

           在我们的代码中时时刻刻都充斥着创建对象,但是你曾今有无思考过,你的对象可以这么创建,也可以那么创建。同时还可以随时随刻切换。这是不

是难以置信?下面我们将会挖掘这其中的奥秘。

 

  1. 抽象工厂模式

1.1 这里我们将会以一个功能来说明其特点。

  • 在如今的Web应用程序中HTML5正在成为趋势,但是仍然不乏很多不支持HTML5的浏览器。但是我们需要开发一个能够让开发者进行绘图的
    通用画布,能够判断浏览器是否支持HTML5,从而决定绘图的方式。

  • 我们的解决方案是公开一个画布的抽象类,并且对于能够创建的各种图形提供统一的接口。

1.2 设计矩形必须具备的特性:

1     abstract class BaseRectangle
2     {
3         //设置边框宽度
4         abstract public void SetLineWidth(int width);
5         //绘制矩形
6         abstract public void DrawRect(int x1, int y1, int x2, int y2);
7     }

 

1.3 设计线条必须具备的特性:

1     abstract class BaseLine
2     {
3         //设置现宽度
4         abstract public void SetWidth(int width);
5         //绘制线
6         abstract public void DrawLine(int x1, int y1, int x2, int y2);
7     }

 

1.4 设计画布必须具备的特性:

1     abstract class CanvasFactory
2     {
3         //创建一个矩形
4         abstract public BaseRectangle CreateRectangle();
5         //创建一条线
6         abstract public BaseLine CreateLine();
7     }

 

1.5 以下用HTML5实现画布功能

1.5.1 HTML5实现画线条

 1     class HTML5Line : BaseLine
 2     {
 3         public override void DrawLine(int x1, int y1, int x2, int y2)
 4         {
 5             Console.WriteLine("draw html5 line!");
 6         }
 7 
 8         public override void SetWidth(int width)
 9         {
10             Console.WriteLine("set html5 line whdth");
11         }
12     }

 

1.5.2 HTML5实现画矩形

 1     class HTML5Rectangle : BaseRectangle
 2     {
 3         public override void DrawRect(int x1, int y1, int x2, int y2)
 4         {
 5             Console.WriteLine("draw html5 rect");
 6         }
 7 
 8         public override void SetLineWidth(int width)
 9         {
10             Console.WriteLine("set html5 rect");
11         }
12     }

 

1.5.3 HTML5实现的画布

 1     class HTML5Canvas : CanvasFactory
 2     {
 3         public override BaseRectangle CreateRectangle()
 4         {
 5             return new HTML5Rectangle();
 6         }
 7 
 8         public override BaseLine CreateLine()
 9         {
10             return new HTML5Line();
11         }
12     }

 

1.6 通过本地Graphical生成图片

1.6.1 Graphical实现画线条

 1     class GraphicalLine : BaseLine
 2     {
 3         public override void DrawLine(int x1, int y1, int x2, int y2)
 4         {
 5             Console.WriteLine("draw graphical line");
 6         }
 7 
 8         public override void SetWidth(int width)
 9         {
10             Console.WriteLine("set graphical line width");
11         }
12     }

 

1.6.2 Graphical实现画矩形

 1     class GraphicalRectangle : BaseRectangle
 2     {
 3         public override void DrawRect(int x1, int y1, int x2, int y2)
 4         {
 5             Console.WriteLine("draw graphical rect");
 6         }
 7 
 8         public override void SetLineWidth(int width)
 9         {
10             Console.WriteLine("set graphical rect width");
11         }
12     }

 

1.6.3 Graphical实现的画布

 1     class GraphicalCanvas : CanvasFactory
 2     {
 3         public override BaseLine CreateLine()
 4         {
 5             return new GraphicalLine();
 6         }
 7 
 8         public override BaseRectangle CreateRectangle()
 9         {
10             return new GraphicalRectangle();
11         }
12     }

 

1.6 下面我们模拟切换使用不同的方式实现画图

 1     class Program
 2     {
 3         static void Draw(CanvasFactory canvas)
 4         {
 5             BaseLine line = canvas.CreateLine();
 6             BaseRectangle rect = canvas.CreateRectangle();
 7             line.SetWidth(1);
 8             line.DrawLine(1,1,2,2);
 9             rect.SetLineWidth(1);
10             rect.DrawRect(1, 1, 2, 2);
11         }
12 
13         static void Main(string[] args)
14         {
15             HTML5Canvas html5 = new HTML5Canvas();
16             GraphicalCanvas graphical = new GraphicalCanvas();
17             //不支持HTML5时
18             bool enabHtml5 = false;
19             if (!enabHtml5)
20             {
21                 Draw(graphical);
22             }
23 
24             //支持HTML5时
25             enabHtml5 = true;
26             if (enabHtml5)
27             {
28                 Draw(html5);
29             }
30             Console.ReadKey();
31         }
32     }

 

 

1.7 结论:

这里我们其实就是公开了一个画布的抽象类以及两种图形的抽象类,用于给客户使用的,而我们程序的内部会决定采用那种方式。这样的好处

就是我们将底层的实现以及类名都隐藏了,同时客户使用的时候只需要关注如何使用,而无需关注是哪个具体的类去实现客户的需求。