设计模式学习笔记十三:外观模式(Facade Pattern)

设计模式学习笔记十三:外观模式(Facade Pattern)

     1.概述
     外观模式(Façade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层的接口,这个接口使得这个子系统更加容易使用。通过这个接口,其他系统可以方便的调用子系统中的功能,而忽略子系统内部发生的变化。
     外观模式(Façade)是经常使用的模式之一,并且可以应用在任何层次和粒度的应用中,小到API的封装,大到封装整个系统。例如在使用ADO.NET时,为了执行SQL,需要使用Connection,Command和DataAdapter等,这样显然比较的麻烦,因此我们可以将整个数据库访问封装到一个类中,该类封装了访问数据库的过程,这个类就是一个外观模式。
     下面我们看外观模式的结构:

设计模式学习笔记十三:外观模式(Facade Pattern)

 

     结构图说明:

     外观类(Facade):客户端可以调用这个类的方法。此类知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本类会将所有从客户端发来的请求委派到相应的子系统去。

子系统(subsystem):可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被外观类调用。子系统并不知道门面的存在,对于子系统而言,外观类仅仅是另外一个客户端而已。

     基本代码:(来自大话设计模式)

     四个子系统类:

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)    public class SubSystemOne
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)        
public void MethodOne()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Console.WriteLine(
" 子系统方法一");
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)    
public class SubSystemTwo
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)        
public void MethodTwo()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Console.WriteLine(
" 子系统方法二");
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)    
public class SubSystemThree
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)        
public void MethodThree()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Console.WriteLine(
" 子系统方法三");
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)    
public class SubSystemFour
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)        
public void MethodFour()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Console.WriteLine(
" 子系统方法四");
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

     外观类:

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)    public class Facade
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)        SubSystemOne one;
设计模式学习笔记十三:外观模式(Facade Pattern)        SubSystemTwo two;
设计模式学习笔记十三:外观模式(Facade Pattern)        SubSystemThree three;
设计模式学习笔记十三:外观模式(Facade Pattern)        SubSystemFour four;
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
public Facade()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            one 
= new SubSystemOne();
设计模式学习笔记十三:外观模式(Facade Pattern)            two 
= new SubSystemTwo();
设计模式学习笔记十三:外观模式(Facade Pattern)            three 
= new SubSystemThree();
设计模式学习笔记十三:外观模式(Facade Pattern)            four 
= new SubSystemFour();
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
public void MethodA()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Console.WriteLine(
"\n方法组A() ---- ");
设计模式学习笔记十三:外观模式(Facade Pattern)            one.MethodOne();
设计模式学习笔记十三:外观模式(Facade Pattern)            two.MethodTwo();
设计模式学习笔记十三:外观模式(Facade Pattern)            four.MethodFour();
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
public void MethodB()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Console.WriteLine(
"\n方法组B() ---- ");
设计模式学习笔记十三:外观模式(Facade Pattern)            two.MethodTwo();
设计模式学习笔记十三:外观模式(Facade Pattern)            three.MethodThree();
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

     客户端调用(由于Facade的作用,客户端可以根本不知道四个子系统类的存在):

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)    public class Program
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)        
static void Main(string[] args)
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Facade facade 
= new Facade();
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            facade.MethodA();
设计模式学习笔记十三:外观模式(Facade Pattern)            facade.MethodB();
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            Console.Read();
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

     2.实例

     数据库访问外观模式:

     在使用ADO.NET访问数据库时,我们通常需要编写下面的访问数据库的语句来访问数据库:

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            SqlConnection myConn = new SqlConnection();
设计模式学习笔记十三:外观模式(Facade Pattern)            myConn.ConnectionString 
= "Database=xxx;Server=local;User Id=sa;Password=123456;";
设计模式学习笔记十三:外观模式(Facade Pattern)            myConn.Open();
设计模式学习笔记十三:外观模式(Facade Pattern)            DataTable dt 
= new DataTable();
设计模式学习笔记十三:外观模式(Facade Pattern)            SqlCommand cmd 
= new SqlCommand(strSQL);
设计模式学习笔记十三:外观模式(Facade Pattern)            SqlDataAdapter da 
= new SqlDataAdapter(cmd);
设计模式学习笔记十三:外观模式(Facade Pattern)            cmd.Connection 
= myConn;
设计模式学习笔记十三:外观模式(Facade Pattern)            da.Fill(dt);
设计模式学习笔记十三:外观模式(Facade Pattern)            myConn.Close();

     如上面的代码所示,为了执行一个SQL,需要使用Connection、Command和DataAdapter,这样显然比较麻烦,因此,我们可以利用外观模式,将数据库访问封装到一个类中,该类分装了访问数据库的过程。下面是给出一个通用的封装的数据访问层,代码如下:

 

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)using System;
设计模式学习笔记十三:外观模式(Facade Pattern)
using System.Data;
设计模式学习笔记十三:外观模式(Facade Pattern)
using System.Collections;
设计模式学习笔记十三:外观模式(Facade Pattern)
namespace DAL
设计模式学习笔记十三:外观模式(Facade Pattern)
{
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// <summary>
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// DALResult 
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// Copyright peida 2008-7-15
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// </summary>

设计模式学习笔记十三:外观模式(Facade Pattern)    public class DALResult
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)        
public bool IsSucceed;            //存储过程是否执行成功
设计模式学习笔记十三:外观模式(Facade Pattern)
        public string errorMessage;        //访问数据库失败
设计模式学习笔记十三:外观模式(Facade Pattern)
        public int rowsCount;            //结果集行数.
设计模式学习笔记十三:外观模式(Facade Pattern)
        public object theFirst;            //第一行第一列
设计模式学习笔记十三:外观模式(Facade Pattern)
        public Hashtable OutputValues;    //存储过程output值,放在(HashTable)表OutputValues里.        
设计模式学习笔记十三:外观模式(Facade Pattern)
        public DataTable datatable;        //存储过程返回的结果集,放在(DataTable)表datatable里.
设计模式学习笔记十三:外观模式(Facade Pattern)
        public DataSet dataSet;            //存储过程返回的结果集,放在DataSet表中
设计模式学习笔记十三:外观模式(Facade Pattern)

设计模式学习笔记十三:外观模式(Facade Pattern)        
public DALResult()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            IsSucceed 
= false;
设计模式学习笔记十三:外观模式(Facade Pattern)            rowsCount 
= 0;
设计模式学习笔记十三:外观模式(Facade Pattern)            errorMessage 
= "";
设计模式学习笔记十三:外观模式(Facade Pattern)            theFirst 
= null;
设计模式学习笔记十三:外观模式(Facade Pattern)            OutputValues 
= new Hashtable();
设计模式学习笔记十三:外观模式(Facade Pattern)            datatable
=new DataTable();
设计模式学习笔记十三:外观模式(Facade Pattern)            dataSet
=new DataSet();
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

设计模式学习笔记十三:外观模式(Facade Pattern)}

      SQL语句的分装:

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)using System;
设计模式学习笔记十三:外观模式(Facade Pattern)
using System.IO;
设计模式学习笔记十三:外观模式(Facade Pattern)
using System.Data;
设计模式学习笔记十三:外观模式(Facade Pattern)
using System.Data.SqlClient;
设计模式学习笔记十三:外观模式(Facade Pattern)
using System.Configuration;
设计模式学习笔记十三:外观模式(Facade Pattern)
using System.Collections;
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)
namespace DAL
设计模式学习笔记十三:外观模式(Facade Pattern)
{
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// <summary>
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// SQL_Base 调用SQL语句
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// Copyright peida 2008-7-15
设计模式学习笔记十三:外观模式(Facade Pattern)    
/// </summary>

设计模式学习笔记十三:外观模式(Facade Pattern)    public class SQL_Base : IDisposable
设计模式学习笔记十三:外观模式(Facade Pattern)    
{
设计模式学习笔记十三:外观模式(Facade Pattern)                
private string strconn = "";
设计模式学习笔记十三:外观模式(Facade Pattern)        
public SQL_Base() : this("")
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            strconn 
= ConfigurationSettings.AppSettings["DBpath"];
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)        
//重载
设计模式学习笔记十三:外观模式(Facade Pattern)
        public SQL_Base(string sql_name)
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            strconn 
= ConfigurationSettings.AppSettings[sql_name];
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)        
//私有成员变量
设计模式学习笔记十三:外观模式(Facade Pattern)
        private string sql_name;
设计模式学习笔记十三:外观模式(Facade Pattern)        
private SqlConnection myConnection;
设计模式学习笔记十三:外观模式(Facade Pattern)        
private SqlCommand myCommand;
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
//公共属性
设计模式学习笔记十三:外观模式(Facade Pattern)
        public string SQLName
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            
get
设计模式学习笔记十三:外观模式(Facade Pattern)            

设计模式学习笔记十三:外观模式(Facade Pattern)                
return this.sql_name; 
设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)            
set
设计模式学习笔记十三:外观模式(Facade Pattern)            

设计模式学习笔记十三:外观模式(Facade Pattern)                
this.sql_name = value; 
设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// <summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// 执行SQL语句,返回数据集:DataTable或DataSet
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// </summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// <returns>返回DALResult</returns>

设计模式学习笔记十三:外观模式(Facade Pattern)        public DALResult ExecuteSqlData()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{            
设计模式学习笔记十三:外观模式(Facade Pattern)            DALResult result 
= new DALResult();
设计模式学习笔记十三:外观模式(Facade Pattern)            myConnection 
= new SqlConnection(strconn);
设计模式学习笔记十三:外观模式(Facade Pattern)            myCommand 
= new SqlCommand(this.sql_name, myConnection);
设计模式学习笔记十三:外观模式(Facade Pattern)            myCommand.CommandType 
= CommandType.Text;
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            SqlDataAdapter myAdapter 
= new SqlDataAdapter(myCommand);    
设计模式学习笔记十三:外观模式(Facade Pattern)        
设计模式学习笔记十三:外观模式(Facade Pattern)            myConnection.Open();
设计模式学习笔记十三:外观模式(Facade Pattern)            
using(SqlTransaction trans  = myConnection.BeginTransaction())
设计模式学习笔记十三:外观模式(Facade Pattern)            
{
设计模式学习笔记十三:外观模式(Facade Pattern)                
try
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    
if(trans!=null)
设计模式学习笔记十三:外观模式(Facade Pattern)                    
{
设计模式学习笔记十三:外观模式(Facade Pattern)                        myCommand.Transaction 
= trans;
设计模式学习笔记十三:外观模式(Facade Pattern)                    }

设计模式学习笔记十三:外观模式(Facade Pattern)                    
设计模式学习笔记十三:外观模式(Facade Pattern)                    
//填充数据,将结果填充到DALResult集中
设计模式学习笔记十三:外观模式(Facade Pattern)
                    myAdapter.Fill(result.dataSet);
设计模式学习笔记十三:外观模式(Facade Pattern)                    
if(result.dataSet.Tables.Count>0)
设计模式学习笔记十三:外观模式(Facade Pattern)                    
{
设计模式学习笔记十三:外观模式(Facade Pattern)                        result.datatable
=result.dataSet.Tables[0].Copy();
设计模式学习笔记十三:外观模式(Facade Pattern)                        
if(result.dataSet.Tables[0].Rows.Count>0)
设计模式学习笔记十三:外观模式(Facade Pattern)                        
{
设计模式学习笔记十三:外观模式(Facade Pattern)                            result.rowsCount 
= result.dataSet.Tables[0].Rows.Count;
设计模式学习笔记十三:外观模式(Facade Pattern)                        }

设计模式学习笔记十三:外观模式(Facade Pattern)                    }

设计模式学习笔记十三:外观模式(Facade Pattern)                    result.IsSucceed 
= true;
设计模式学习笔记十三:外观模式(Facade Pattern)                    
//提交事物
设计模式学习笔记十三:外观模式(Facade Pattern)
                    trans.Commit();
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)                
catch(Exception e)
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    result.errorMessage 
= e.Message;
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)                
//如果捕捉了异常,但仍会执行包括在 finally 块中的输出语句
设计模式学习笔记十三:外观模式(Facade Pattern)
                finally
设计模式学习笔记十三:外观模式(Facade Pattern)                
{                    
设计模式学习笔记十三:外观模式(Facade Pattern)                    myAdapter.Dispose();
设计模式学习笔记十三:外观模式(Facade Pattern)                    myCommand.Dispose();
设计模式学习笔记十三:外观模式(Facade Pattern)                    myConnection.Close();
设计模式学习笔记十三:外观模式(Facade Pattern)                    myConnection.Dispose();                
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)            
return result;
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// <summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// 获取第一行第一列数据
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// </summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// <returns>返回DALResult</returns>

设计模式学习笔记十三:外观模式(Facade Pattern)        public DALResult ExecuteSqlScalar()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            DALResult result 
= new DALResult();
设计模式学习笔记十三:外观模式(Facade Pattern)            myConnection 
= new SqlConnection(strconn);
设计模式学习笔记十三:外观模式(Facade Pattern)            myCommand 
= new SqlCommand(this.sql_name, myConnection);
设计模式学习笔记十三:外观模式(Facade Pattern)            myCommand.CommandType 
= CommandType.Text;
设计模式学习笔记十三:外观模式(Facade Pattern)        
设计模式学习笔记十三:外观模式(Facade Pattern)            myConnection.Open();
设计模式学习笔记十三:外观模式(Facade Pattern)            
using(SqlTransaction trans  = myConnection.BeginTransaction())
设计模式学习笔记十三:外观模式(Facade Pattern)            
{
设计模式学习笔记十三:外观模式(Facade Pattern)                
try
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    
if(trans!=null)
设计模式学习笔记十三:外观模式(Facade Pattern)                    
{
设计模式学习笔记十三:外观模式(Facade Pattern)                        myCommand.Transaction 
= trans;                        
设计模式学习笔记十三:外观模式(Facade Pattern)                    }

设计模式学习笔记十三:外观模式(Facade Pattern)                    
object scalarresult = myCommand.ExecuteScalar();
设计模式学习笔记十三:外观模式(Facade Pattern)                    
if(Object.Equals(scalarresult,null))
设计模式学习笔记十三:外观模式(Facade Pattern)                    
{
设计模式学习笔记十三:外观模式(Facade Pattern)                        result.errorMessage 
= "没有取到数据";
设计模式学习笔记十三:外观模式(Facade Pattern)                    }

设计模式学习笔记十三:外观模式(Facade Pattern)                    
else
设计模式学习笔记十三:外观模式(Facade Pattern)                    
{
设计模式学习笔记十三:外观模式(Facade Pattern)                        result.theFirst 
= scalarresult;
设计模式学习笔记十三:外观模式(Facade Pattern)                        
//取到数据
设计模式学习笔记十三:外观模式(Facade Pattern)
                        result.rowsCount=1;
设计模式学习笔记十三:外观模式(Facade Pattern)                    }

设计模式学习笔记十三:外观模式(Facade Pattern)                    result.IsSucceed 
= true;
设计模式学习笔记十三:外观模式(Facade Pattern)                    
//提交事物
设计模式学习笔记十三:外观模式(Facade Pattern)
                    trans.Commit();
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)                
catch(Exception e)
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    result.errorMessage 
= e.Message;
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)                
finally
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    myCommand.Dispose();
设计模式学习笔记十三:外观模式(Facade Pattern)                    myConnection.Close();
设计模式学习笔记十三:外观模式(Facade Pattern)                    myConnection.Dispose();                
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)            
return result;
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// <summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// 执行无返回结果的SQL语句
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// </summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// <returns>返回DALResult</returns>

设计模式学习笔记十三:外观模式(Facade Pattern)        public DALResult ExecuteSqlNonQuery()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            DALResult result 
= new DALResult();
设计模式学习笔记十三:外观模式(Facade Pattern)            myConnection 
= new SqlConnection(strconn);
设计模式学习笔记十三:外观模式(Facade Pattern)            myCommand 
= new SqlCommand(this.sql_name, myConnection);
设计模式学习笔记十三:外观模式(Facade Pattern)            myCommand.CommandType 
= CommandType.Text;
设计模式学习笔记十三:外观模式(Facade Pattern)        
设计模式学习笔记十三:外观模式(Facade Pattern)            myConnection.Open();
设计模式学习笔记十三:外观模式(Facade Pattern)            
using(SqlTransaction trans  = myConnection.BeginTransaction())
设计模式学习笔记十三:外观模式(Facade Pattern)            
{
设计模式学习笔记十三:外观模式(Facade Pattern)                
try
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    
if(trans!=null)
设计模式学习笔记十三:外观模式(Facade Pattern)                    
{
设计模式学习笔记十三:外观模式(Facade Pattern)                        myCommand.Transaction 
= trans;
设计模式学习笔记十三:外观模式(Facade Pattern)                    }

设计模式学习笔记十三:外观模式(Facade Pattern)                    myCommand.ExecuteNonQuery();
设计模式学习笔记十三:外观模式(Facade Pattern)                    result.IsSucceed 
= true;
设计模式学习笔记十三:外观模式(Facade Pattern)                    
//提交事物
设计模式学习笔记十三:外观模式(Facade Pattern)
                    trans.Commit();
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)                
catch(Exception e)
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    result.errorMessage 
= e.Message;
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)                
finally
设计模式学习笔记十三:外观模式(Facade Pattern)                
{
设计模式学习笔记十三:外观模式(Facade Pattern)                    myCommand.Dispose();
设计模式学习笔记十三:外观模式(Facade Pattern)                    myConnection.Close();
设计模式学习笔记十三:外观模式(Facade Pattern)                    myConnection.Dispose();                
设计模式学习笔记十三:外观模式(Facade Pattern)                }

设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)            
return result;
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// <summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// ExecuteReader
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// 
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// </summary>
设计模式学习笔记十三:外观模式(Facade Pattern)        
/// 

设计模式学习笔记十三:外观模式(Facade Pattern)        public SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            SqlCommand cmd 
= new SqlCommand();
设计模式学习笔记十三:外观模式(Facade Pattern)            SqlConnection conn 
= new SqlConnection(strconn);
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            
// we use a try/catch here because if the method throws an exception we want to 
设计模式学习笔记十三:外观模式(Facade Pattern)            
// close the connection throw code, because no datareader will exist, hence the 
设计模式学习笔记十三:外观模式(Facade Pattern)            
// commandBehaviour.CloseConnection will not work
设计模式学习笔记十三:外观模式(Facade Pattern)
            try
设计模式学习笔记十三:外观模式(Facade Pattern)            
{
设计模式学习笔记十三:外观模式(Facade Pattern)                PrepareCommand(cmd, conn, 
null, cmdType, cmdText, commandParameters);
设计模式学习笔记十三:外观模式(Facade Pattern)                SqlDataReader rdr 
= cmd.ExecuteReader(CommandBehavior.CloseConnection);
设计模式学习笔记十三:外观模式(Facade Pattern)                cmd.Parameters.Clear();
设计模式学习笔记十三:外观模式(Facade Pattern)                
return rdr;
设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)            
catch
设计模式学习笔记十三:外观模式(Facade Pattern)            
{
设计模式学习笔记十三:外观模式(Facade Pattern)                conn.Close();
设计模式学习笔记十三:外观模式(Facade Pattern)                
throw;
设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)        
private void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            
if (conn.State != ConnectionState.Open)
设计模式学习笔记十三:外观模式(Facade Pattern)                conn.Open();
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            cmd.Connection 
= conn;
设计模式学习笔记十三:外观模式(Facade Pattern)            cmd.CommandText 
= cmdText;
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            
if (trans != null)
设计模式学习笔记十三:外观模式(Facade Pattern)                cmd.Transaction 
= trans;
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            cmd.CommandType 
= cmdType;
设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)            
if (cmdParms != null)
设计模式学习笔记十三:外观模式(Facade Pattern)            
{
设计模式学习笔记十三:外观模式(Facade Pattern)                
foreach (SqlParameter parm in cmdParms)
设计模式学习笔记十三:外观模式(Facade Pattern)                    cmd.Parameters.Add(parm);
设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
public void Dispose()
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            Dispose(
true);
设计模式学习笔记十三:外观模式(Facade Pattern)            GC.SuppressFinalize(
true);
设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)
设计模式学习笔记十三:外观模式(Facade Pattern)        
protected virtual void Dispose(bool disposing)
设计模式学习笔记十三:外观模式(Facade Pattern)        
{
设计模式学习笔记十三:外观模式(Facade Pattern)            
if (! disposing)
设计模式学习笔记十三:外观模式(Facade Pattern)                
return
设计模式学习笔记十三:外观模式(Facade Pattern)            
if(myConnection != null)
设计模式学习笔记十三:外观模式(Facade Pattern)            
{
设计模式学习笔记十三:外观模式(Facade Pattern)                myConnection.Dispose();
设计模式学习笔记十三:外观模式(Facade Pattern)            }

设计模式学习笔记十三:外观模式(Facade Pattern)        }

设计模式学习笔记十三:外观模式(Facade Pattern)    }

设计模式学习笔记十三:外观模式(Facade Pattern)}

设计模式学习笔记十三:外观模式(Facade Pattern)

     存储过程的封装:

 

设计模式学习笔记十三:外观模式(Facade Pattern)
using System;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace DAL
{
    
/// <summary>
    
///调用存储过程
    
///Copyright Peida 2008-7-15
    
/// </summary>
    public class SP_Base : IDisposable
    {
        
public SP_Base() : this("")
        {
        }
        
//重载
        public SP_Base(string sql_name)
        {
            
this.sp_name = sp_name;
        }
        
//私有成员变量
        private string strconn=ConfigurationSettings.AppSettings["DBpath"];
        
private string sp_name; 
        
private SqlConnection myConnection;
        
private SqlCommand myCommand;
        
//存储过程参数
        private SqlParameter myParameter;
        
        
//公共属性
        public string ProcedureName
        {
            
get
            { 
                
return this.sp_name; 
            }
            
set
            { 
                
this.sp_name = value; 
            }
        }        

        
//========begin=========
        /// <summary>
        
/// 调用存储过程
        
/// </summary>
        
/// <param name="parameters">参数集合</param>
        
/// <returns></returns>
        public  DALResult Call_SP(params object[] parameters)
        {
            DALResult result 
= new DALResult();
            myConnection  
= new SqlConnection(strconn);            
            myCommand 
= new SqlCommand(this.ProcedureName, myConnection);
            myCommand.CommandType 
= CommandType.StoredProcedure;            
            SqlDataAdapter myAdapter 
= new SqlDataAdapter(myCommand);    

            myConnection.Open();
            GetProcedureParameter(result,parameters);
            
//事物
            using(SqlTransaction trans = myConnection.BeginTransaction())
            {
                
try
                {                    
                    
if(trans!=null)
                    {
                        myCommand.Transaction 
= trans;
                    }
                    
//填充数据,将结果填充到DALResult集中
                    myAdapter.Fill(result.dataSet);
                    
if(result.dataSet.Tables.Count>0)
                    {
                        result.datatable
=result.dataSet.Tables[0].Copy();
                        
if(result.dataSet.Tables[0].Rows.Count>0)
                        {
                            result.rowsCount 
= result.dataSet.Tables[0].Rows.Count;
                        }
                    }
                    result.IsSucceed 
= true;                    
                                
                    
//将输出参数的值添加到Result
                    GetOutputValue(result);
                    
//提交事物
                    trans.Commit();
                }
                
catch(Exception e)
                {
                    result.errorMessage 
= e.Message;
                    
//事物回滚
                    trans.Rollback();
                }
                
                
//如果捕捉了异常,但仍会执行包括在 finally 块中的输出语句
                finally
                {
                    myAdapter.Dispose();
                    myCommand.Dispose();
                    myConnection.Close();
                    myConnection.Dispose();
                }
            }
            
return result;
        }

        
/// <summary>
        
/// 将参数添加到存储过程的参数集合
        
/// </summary>
        
/// <param name="parameters"></param>
        private void GetProcedureParameter(DALResult result,params object[] parameters)
        {
            SqlCommand myCommand2 
= new SqlCommand();
            myCommand2.Connection 
= this.myConnection;
            myCommand2.CommandText 
= "select * from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME='" +this.ProcedureName+ "' order by ORDINAL_POSITION";
            SqlDataReader reader 
= null;
            
try 
            {
                reader 
= myCommand2.ExecuteReader();
                
int i = 0;
                
while(reader.Read())
                {
                    myParameter 
= new SqlParameter();
                    myParameter.ParameterName 
= reader["PARAMETER_NAME"].ToString();
                    myParameter.Direction 
= reader["PARAMETER_MODE"].ToString()=="IN"?ParameterDirection.Input:ParameterDirection.Output;
                    
                    
switch(reader["DATA_TYPE"].ToString())
                    {
                        
case "bit" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= Convert.ToBoolean(parameters[i]);
                            myParameter.SqlDbType 
= SqlDbType.Bit;
                            
break;
                        
                        
case "bigint":
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= Convert.ToInt32(parameters[i]);
                            myParameter.SqlDbType 
= SqlDbType.BigInt;
                            
break;
                       
                        
case "int" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= Convert.ToInt32(parameters[i].ToString());
                            myParameter.SqlDbType 
= SqlDbType.Int;
                            
break;

                        
case "decimal" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= (decimal)parameters[i];
                            myParameter.SqlDbType 
= SqlDbType.Decimal;
                            myParameter.Precision 
= (byte)reader["NUMERIC_PRECISION"];
                            myParameter.Scale 
= byte.Parse(reader["NUMERIC_SCALE"].ToString());
                            
break;

                        
case "nvarchar" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= Convert.ToString(parameters[i]);
                            myParameter.Size 
= Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]);
                            myParameter.SqlDbType 
= SqlDbType.NVarChar;
                            
break;

                        
case "varchar" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= (string)parameters[i];
                            myParameter.Size 
= Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]);
                            myParameter.SqlDbType 
= SqlDbType.VarChar;
                            
break;

                        
case "nchar" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= (string)parameters[i];
                            myParameter.Size 
= Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]);
                            myParameter.SqlDbType 
= SqlDbType.NChar;
                            
break;

                        
case "char" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= (string)parameters[i];
                            myParameter.Size 
= Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]);
                            myParameter.SqlDbType 
= SqlDbType.Char;
                            
break;

                        
case "ntext" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= (string)parameters[i];
                            myParameter.SqlDbType 
= SqlDbType.NText;
                            
break;
                      
                        
case "text" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= (string)parameters[i];
                            myParameter.SqlDbType 
= SqlDbType.Text;
                            
break;
                       
                        
case "datetime" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= Convert.ToDateTime(parameters[i]);
                            myParameter.SqlDbType 
= SqlDbType.DateTime;
                            
break
                 
                        
case "smalldatetime" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                                myParameter.Value 
= Convert.ToDateTime(parameters[i]);
                            myParameter.SqlDbType 
= SqlDbType.DateTime;
                            
break;      
                 
                        
case "image" :
                            
if(myParameter.Direction == ParameterDirection.Input)
                            {
                                myParameter.Value
=(byte[])parameters[i];                            
                            }
                            myParameter.SqlDbType 
= SqlDbType.Image;
                            
break;

                        
case "real":
                            
if(myParameter.Direction==ParameterDirection.Input)
                                myParameter.Value
=Convert.ToSingle(parameters[i]);
                            myParameter.SqlDbType 
= SqlDbType.Real;
                            
break;    
                        
case "varbinary":
                            
if(myParameter.Direction==ParameterDirection.Input)
                                myParameter.Value
=(byte[])parameters[i];
                            myParameter.SqlDbType 
= SqlDbType.VarBinary;
                            
break;

                        
default : 
                            
break;
                    }
                    i
++;
                    myCommand.Parameters.Add(myParameter);
                }
            }
            
catch(Exception e)
            {
                result.errorMessage 
= e.Message;
            }
            
finally
            {
                
if(reader!=null)
                {
                    reader.Close();
                }
                myCommand2.Dispose();
            }
        }

        
/// <summary>
        
/// 将输出的值添加到Result的OutputValues
        
/// </summary>
        
/// <param name="result"></param>
        private void GetOutputValue(DALResult result)
        {
            
foreach(SqlParameter parameter in myCommand.Parameters)
            {
                
if(parameter.Direction == ParameterDirection.Output)
                {
                    
//Hashtab表是一个键值对
                    result.OutputValues.Add(parameter.ParameterName, parameter.Value);
                }
            }
        }

        
public void Dispose()
        {
            Dispose(
true);
            GC.SuppressFinalize(
true);
        }

        
protected virtual void Dispose(bool disposing)
        {
            
if (! disposing)
                
return
            
if(myConnection != null)
            {
                myConnection.Dispose();
            }
        }
        
//=======end======
    }
}

     3.总结

     何时采用外观模式:

     从代码角度来说, 如果你的程序有多个类是和一组其它接口发生关联的话可以考虑在其中加一个外观类型。
     从应用角度来说, 如果子系统的接口是非常细的,调用方也有大量的逻辑来和这些接口发生关系,那么就可以考虑使用Facade把客户端与子系统的直接耦合关系进行化解。你可能会说,子系统改了外观类不是照样改?的确是需要改,但是如果客户端本身的工作已经比较复杂,或者说可能有多个需要调用外观类的地方,这个时候外观类的好处就体现了。

 

     效果及实现要点

     1.Facade模式对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。

     2.Facade模式实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。

     3.如果应用需要,它并不限制它们使用子系统类。因此你可以在系统易用性与通用性之间选择。

     4.通过一个高层接口让子系统和客户端不发生直接关联,使客户端不受子系统变化的影响。

     5.Facade不仅仅针对代码级别,在构架上,特别是WEB应用程序的构架上,Facade的应用非常普遍。如常常说的三层架构就是典型的外观模式。

 

     参考资料:

     大话设计模式

     http://terrylee.cnblogs.com/archive/2006/03/17/352349.html

     http://www.cnblogs.com/lovecherry/archive/2007/10/07/916202.html