昨天和今天一直在看大家发的有关于架构的问题,看多了最后反而到把自己给弄迷糊了。复杂的架构我也不会,评论任何,或许等到哪一天我由一个菜鸟变成一个高手以后,嘿嘿,偶也会去弄一些高深的文章。

      关于3层,如果你和我一样是一个刚起步不久的,而且对开发架构有一定兴趣的人,那么以下我写的内容或许对大家认识三层有个形象的了解。

      使用n层架构,需要把应用程序的逻辑封装到独立的层中去。大多数情况下,一个Application被推荐分为3层,即:用户界面层、业务逻辑层、数据访问层。

      下面,我用一个从书上学来的经典3层例子给大家详细分析一下3层,同时自己也巩固一下。

      简单设计模式的认识
         (该图是数据库中的表和字段,以下操作均围绕该表进行)  

        首先,我们从数据访问层开始说起,数据访问层封装包含操作数据库的所有代码。以下代码均封装在SamlpeDAL类库下。

 Product
    {
        private int _id;

        public int ID
        {
            
get { return _id; }
            
set { _id = value; }
        }

        private string _name;

        public string Name
        {
            
get { return _name; }
            
set { _name = value; }
        }

        private decimal _price;

        public decimal Price
        {
            
get { return _price; }
            
set { _price = value; }
        }

        private string _description;

        public string Description
        {
            
get { return _description; }
            
set { _description = value; }
        }

        public Product(int id,string name,decimal price,string description)
        {
            _id 
= id;
            _name 
= name;
            _price 
= price;
            _description 
= description;
        }

        public Product(string name, decimal price, string description)
            : 
this(0, name, price, description)
        { }
    }

(如果你对抽象工厂开发模式也有研究的话,其实实体类应该放在Model层下的)

 SqlDataAccess
    {
        private static readonly string _connString = string.Empty;

        static SqlDataAccess()
        {
            _connString 
= "server=.\\mssql2005;database=dbProduct;user=sa;pwd=welcome";
        }

        public List<Product> ProductSelectAll()
        {
            List
<Product> products = new List<Product>();
            SqlConnection objConn 
= new SqlConnection(_connString);
            SqlCommand objComm 
= new SqlCommand();
            objComm.Connection 
= objConn;
            objComm.CommandText 
= "select * from products";
            
using (objConn)
            {
                objConn.Open();
                SqlDataReader objReader 
= objComm.ExecuteReader();
                
while (objReader.Read())
                {
                    products.Add(
new Product(
                        (
int)objReader["Id"],
                        (
string)objReader["Name"], 
                        (
decimal)objReader["Price"],
                        (
string)objReader["Description"]));
                }
                
return products;
            }
        }

        public void ProductInsert(Product newProduct)
        {
            SqlConnection objConn 
= new SqlConnection(_connString);
            SqlCommand objComm 
= new SqlCommand();
            objComm.Connection 
= objConn;
            objComm.CommandText 
= "insert Products(Name,Price,Description) values(@Name,@Price,@Description)";
            objComm.Parameters.AddWithValue(
"@Name", newProduct.Name);
            objComm.Parameters.AddWithValue(
"@Price", newProduct.Price);
            objComm.Parameters.AddWithValue(
"@Description",newProduct.Description);
            
using (objConn)
            {
                objConn.Open();
                objComm.ExecuteNonQuery();
            }
        }

        public void ProductUpdate(Product productToUpdate)
        {
            SqlConnection objConn 
= new SqlConnection(_connString);
            SqlCommand objComm 
= new SqlCommand();
            objComm.Connection 
= objConn;
            objComm.CommandText 
= "update Products set Name=@Name,"
                
+"Price=@Price,Description=@Description where Id=@Id";
            objComm.Parameters.AddWithValue(
"@Name", productToUpdate.Name);
            objComm.Parameters.AddWithValue(
"@Price",productToUpdate.Price);
            objComm.Parameters.AddWithValue(
"@Description",productToUpdate.Description);
            objComm.Parameters.AddWithValue(
"@Id",productToUpdate.ID);
            
using (objConn)
            {
                objConn.Open();
                objComm.ExecuteNonQuery();
            }
        }

        public void ProductDelete(int id)
        {
            SqlConnection objConn 
= new SqlConnection(_connString);
            SqlCommand objComm 
= new SqlCommand();
            objComm.Connection 
= objConn;
            objComm.CommandText 
= "delete Products where Id=@Id";
            objComm.Parameters.AddWithValue(
"@Id", id);
            
using (objConn)
            {
                objConn.Open();
                objComm.ExecuteNonQuery();
            }
        }
    }

 

      接下来再给大家介绍一下业务逻辑层。业务逻辑层包含所有的商务规则和验证代码,并管理所有界面的数据访问。以下的代码封装在SampleBLL类库中。


    public class BusinessLogic
    {
        
public static List<Product> SelectAll()
        {
            SqlDataAccess objSqlDataAccess 
= new SqlDataAccess();
            
return objSqlDataAccess.ProductSelectAll();
        }

        public static void Update(int id, string name, decimal price, string description)
        {
            Product objProduct 
= new Product(id, name, price, description);
            SqlDataAccess objSqlDataAccess 
= new SqlDataAccess();
            objSqlDataAccess.ProductUpdate(objProduct);
        }

        public static void Insert(string name, decimal price, string description)
        {
            Product objProduct 
= new Product(name, price, description);
            SqlDataAccess objSqlDataAccess 
= new SqlDataAccess();
            objSqlDataAccess.ProductInsert(objProduct);
        }

        public static void Delete(int id)
        {
            SqlDataAccess objSqlDataAccess 
= new SqlDataAccess();
            objSqlDataAccess.ProductDelete(id);
        }
    }

 

      最后,我们来介绍用户界面层。用户界面层除了界面元素外,不应该包含任何其他内容。用户界面层也不应该包含任何业务逻辑和数据访问。这个例子的用户界面层封装在名为SampleUI的Web Application库中。其效果如图:

                      简单设计模式的认识


    <form id="form1" runat="server">
    
<div>
        
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" DataKeyNames="ID">
            
<Columns>
                
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" ReadOnly="True" />
                
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
                
<asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" />
                
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
                
<asp:CommandField CancelText="Cancel" DeleteText="Delete" EditText="Edit" ShowEditButton="True"
                    UpdateText
="Update" />
                
<asp:CommandField DeleteText="Delete" ShowDeleteButton="True" />
            
</Columns>
        
</asp:GridView>
        
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="Delete"
            InsertMethod
="Insert" SelectMethod="SelectAll" TypeName="SampleBLL.BusinessLogic"
            UpdateMethod
="Update">
            
<DeleteParameters>
                
<asp:Parameter Name="id" Type="Int32" />
            
</DeleteParameters>
            
<UpdateParameters>
                
<asp:Parameter Name="id" Type="Int32" />
                
<asp:Parameter Name="name" Type="String" />
                
<asp:Parameter Name="price" Type="Decimal" />
                
<asp:Parameter Name="description" Type="String" />
            
</UpdateParameters>
            
<InsertParameters>
                
<asp:Parameter Name="name" Type="String" />
                
<asp:Parameter Name="price" Type="Decimal" />
                
<asp:Parameter Name="description" Type="String" />
            
</InsertParameters>
        
</asp:ObjectDataSource>
        
<br />
        
&nbsp;<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
            DataSourceID
="ObjectDataSource1" DefaultMode="Insert" Height="50px" Width="125px">
            
<Fields>
                
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
                
<asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" />
                
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
                
<asp:CommandField ShowInsertButton="True" />
            
</Fields>
        
</asp:DetailsView>
    
</div>
    
</form>
</body>

 

      从以上所有代码中我们不难看出3层是怎样分开封装,以及3个层之间的是怎样关联工作的。这里值得注意的是,如果你用的是VS,那么这三个层被放在同一个解决方案中是毫无疑问的,只是在一个层中使用另一个层的文件时,记得在引用中添加另一个层即可。