`

这也是一种抽象工厂

阅读更多
这也是一种抽象工厂

抽象工厂模式
The abstract factory is a GOF (Gang of Four) creational pattern where the intent is to "...provide an interface for creating families of related or dependent objects without specifying their concrete classes". ("Design Patterns" -- Gamma, Help, Johnson, Vlissides)

抽象工厂模式是一种创建型模式,意图是“提供一个创建一系列相关或相互依赖对象的接口,而不需要指定它们具体的类”。(《Design Patterns》GOF)
There are four main parts to any abstract factory:

Abstract Factory: defines generic interface for creation of objects.
Concrete Factory: implementation of the abstract factory.
Abstract Product: the generic interface that defines the object to be created.
Concrete Product: the implementation of the abstract product.  In other words, the actual objects.
任何抽象工厂都包含以下四大部分:

抽象工厂:为创建对象提供一般接口。
具体工厂:抽象工厂的实现。
抽象产品:定义了被创建对象的一般接口。
具体产品:抽象产品的实现,即实际对象。

抽象工厂模式在Pet Shop中的应用
可能有多处应用,我们先从DataAccess这一处最明显的地方讲起。对于Pet Shop中那么多DLL的关系以及讲解可以查阅微软相关资料,我不做过多讲解。
这里首先要明白Pet Shop可以连接多个数据库,这就符合GOF的抽象工厂模式的意图:提供一个创建一系列相关或相互依赖对象的接口,而不需要指定它们具体的类。

在PetShop.BLL命名空间中类说起。
至于那些类中的代理模式之类以后再进行说明。现在引用一些代码如下:
 public class Product {

     private static readonly IProduct dal = PetShop.DALFactory.DataAccess.CreateProduct();  


在这里我们主要要看的是PetShop.DALFactory.DataAccess.CreateProduct(); 
查看定义DataAccess.cs
using System.Reflection;
using System.Configuration;

namespace PetShop.DALFactory {

    /// <summary>
    /// This class is implemented following the Abstract Factory pattern to create the DAL implementation
    /// specified from the configuration file
    /// </summary>
    public sealed class DataAccess {

        // Look up the DAL implementation we should be using
        private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
        private static readonly string orderPath = ConfigurationManager.AppSettings["OrdersDAL"];
        
        private DataAccess() { }

        public static PetShop.IDAL.ICategory CreateCategory() {
            string className = path + ".Category";
            return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
        }

        public static PetShop.IDAL.IInventory CreateInventory() {
            string className = path + ".Inventory";
            return (PetShop.IDAL.IInventory)Assembly.Load(path).CreateInstance(className);
        }

        public static PetShop.IDAL.IItem CreateItem() {
            string className = path + ".Item";
            return (PetShop.IDAL.IItem)Assembly.Load(path).CreateInstance(className);
        }

        public static PetShop.IDAL.IOrder CreateOrder() {
            string className = orderPath + ".Order";
            return (PetShop.IDAL.IOrder)Assembly.Load(orderPath).CreateInstance(className);
        }

        public static PetShop.IDAL.IProduct CreateProduct() {
            string className = path + ".Product";
            return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
        }

    }
}


这里的代码起到框架做用,通过配置文件来自动生成找到工厂类。
开始以为是抽象工厂方法,但是查看了一下,不是,是通过反射直接创建类。也可以理解为一种更简单的抽象工厂。
IDAL 中定义接口,如
IOrder.cs
using System;

//References to PetShop specific libraries
//PetShop busines entity library
using PetShop.Model;

namespace PetShop.IDAL{
	
	/// <summary>
	/// Interface for the Order DAL
	/// </summary>
	public interface IOrder {

		/// <summary>
		/// Method to insert an order header
		/// </summary>
		/// <param name="order">Business entity representing the order</param>
		/// <returns>OrderId</returns>
		void Insert(OrderInfo order);

		/// <summary>
		/// Reads the order information for a given orderId
		/// </summary>
		/// <param name="orderId">Unique identifier for an order</param>
		/// <returns>Business entity representing the order</returns>
		OrderInfo GetOrder(int orderId);
	}
}

其中不同的数据库有不同的实现类,在SQLServerDAL中的实现:
Order.cs
using System;
using System.Data.SqlClient;
using System.Data;
using System.Collections.Generic;
using System.Text;
using PetShop.Model;
using PetShop.IDAL;
using PetShop.DBUtility;

namespace PetShop.SQLServerDAL {

    public class Order : IOrder {

        //Static constants
		private const string SQL_INSERT_ORDER = "Declare @ID int; Declare @ERR int; INSERT INTO Orders VALUES(@UserId, @Date, @ShipAddress1, @ShipAddress2, @ShipCity, @ShipState, @ShipZip, @ShipCountry, @BillAddress1, @BillAddress2, @BillCity, @BillState, @BillZip, @BillCountry, 'UPS', @Total, @BillFirstName, @BillLastName, @ShipFirstName, @ShipLastName, @AuthorizationNumber, 'US_en'); SELECT @ID=@@IDENTITY; INSERT INTO OrderStatus VALUES(@ID, @ID, GetDate(), 'P'); SELECT @ERR=@@ERROR;";
        private const string SQL_INSERT_ITEM = "INSERT INTO LineItem VALUES( ";
        private const string SQL_SELECT_ORDER = "SELECT o.OrderDate, o.UserId, o.CardType, o.CreditCard, o.ExprDate, o.BillToFirstName, o.BillToLastName, o.BillAddr1, o.BillAddr2, o.BillCity, o.BillState, BillZip, o.BillCountry, o.ShipToFirstName, o.ShipToLastName, o.ShipAddr1, o.ShipAddr2, o.ShipCity, o.ShipState, o.ShipZip, o.ShipCountry, o.TotalPrice, l.ItemId, l.LineNum, l.Quantity, l.UnitPrice FROM Orders as o, lineitem as l WHERE o.OrderId = @OrderId AND o.orderid = l.orderid";
        private const string PARM_USER_ID = "@UserId";
        private const string PARM_DATE = "@Date";
        private const string PARM_SHIP_ADDRESS1 = "@ShipAddress1";
        private const string PARM_SHIP_ADDRESS2 = "@ShipAddress2";
        private const string PARM_SHIP_CITY = "@ShipCity";
        private const string PARM_SHIP_STATE = "@ShipState";
        private const string PARM_SHIP_ZIP = "@ShipZip";
        private const string PARM_SHIP_COUNTRY = "@ShipCountry";
        private const string PARM_BILL_ADDRESS1 = "@BillAddress1";
        private const string PARM_BILL_ADDRESS2 = "@BillAddress2";
        private const string PARM_BILL_CITY = "@BillCity";
        private const string PARM_BILL_STATE = "@BillState";
        private const string PARM_BILL_ZIP = "@BillZip";
        private const string PARM_BILL_COUNTRY = "@BillCountry";
        private const string PARM_TOTAL = "@Total";
        private const string PARM_BILL_FIRST_NAME = "@BillFirstName";
        private const string PARM_BILL_LAST_NAME = "@BillLastName";
        private const string PARM_SHIP_FIRST_NAME = "@ShipFirstName";
        private const string PARM_SHIP_LAST_NAME = "@ShipLastName";
		private const string PARM_AUTHORIZATION_NUMBER = "@AuthorizationNumber";  
        private const string PARM_ORDER_ID = "@OrderId";
        private const string PARM_LINE_NUMBER = "@LineNumber";
        private const string PARM_ITEM_ID = "@ItemId";
        private const string PARM_QUANTITY = "@Quantity";
        private const string PARM_PRICE = "@Price";

        public void Insert(OrderInfo order) {
            StringBuilder strSQL = new StringBuilder();

            // Get each commands parameter arrays
            SqlParameter[] orderParms = GetOrderParameters();

            SqlCommand cmd = new SqlCommand();

            // Set up the parameters
            orderParms[0].Value = order.UserId;
            orderParms[1].Value = order.Date;
            orderParms[2].Value = order.ShippingAddress.Address1;
            orderParms[3].Value = order.ShippingAddress.Address2;
            orderParms[4].Value = order.ShippingAddress.City;
            orderParms[5].Value = order.ShippingAddress.State;
            orderParms[6].Value = order.ShippingAddress.Zip;
            orderParms[7].Value = order.ShippingAddress.Country;
            orderParms[8].Value = order.BillingAddress.Address1;
            orderParms[9].Value = order.BillingAddress.Address2;
            orderParms[10].Value = order.BillingAddress.City;
            orderParms[11].Value = order.BillingAddress.State;
            orderParms[12].Value = order.BillingAddress.Zip;
            orderParms[13].Value = order.BillingAddress.Country;
            orderParms[14].Value = order.OrderTotal;
            orderParms[15].Value = order.BillingAddress.FirstName;
            orderParms[16].Value = order.BillingAddress.LastName;
            orderParms[17].Value = order.ShippingAddress.FirstName;
            orderParms[18].Value = order.ShippingAddress.LastName;
			orderParms[19].Value = order.AuthorizationNumber.Value;

            foreach (SqlParameter parm in orderParms)
                cmd.Parameters.Add(parm);

            // Create the connection to the database
            using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringOrderDistributedTransaction)) {

                // Insert the order status
                strSQL.Append(SQL_INSERT_ORDER);
                SqlParameter[] itemParms;
                // For each line item, insert an orderline record
                int i = 0;
                foreach (LineItemInfo item in order.LineItems) {
                    strSQL.Append(SQL_INSERT_ITEM).Append(" @ID").Append(", @LineNumber").Append(i).Append(", @ItemId").Append(i).Append(", @Quantity").Append(i).Append(", @Price").Append(i).Append("); SELECT @ERR=@ERR+@@ERROR;");

                    //Get the cached parameters
                    itemParms = GetItemParameters(i);

                    itemParms[0].Value = item.Line;
                    itemParms[1].Value = item.ItemId;
                    itemParms[2].Value = item.Quantity;
                    itemParms[3].Value = item.Price;
                    //Bind each parameter
                    foreach (SqlParameter parm in itemParms)
                        cmd.Parameters.Add(parm);
                    i++;
                }

                conn.Open();
                cmd.Connection = conn;
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = strSQL.Append("SELECT @ID, @ERR").ToString();

                // Read the output of the query, should return error count
                using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) {
                    // Read the returned @ERR
                    rdr.Read();
                    // If the error count is not zero throw an exception
                    if (rdr.GetInt32(1) != 0)
                        throw new ApplicationException("DATA INTEGRITY ERROR ON ORDER INSERT - ROLLBACK ISSUED");
                }
                //Clear the parameters
                cmd.Parameters.Clear();
            }
        }

        /// <summary>
        /// Read an order from the database
        /// </summary>
        /// <param name="orderId">Order Id</param>
        /// <returns>All information about the order</returns>
        public OrderInfo GetOrder(int orderId) {

            OrderInfo order = new OrderInfo();

            //Create a parameter
            SqlParameter parm = new SqlParameter(PARM_ORDER_ID, SqlDbType.Int);
            parm.Value = orderId;

            //Execute a query to read the order
            using (SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringOrderDistributedTransaction, CommandType.Text, SQL_SELECT_ORDER, parm)) {

                if (rdr.Read()) {

                    //Generate an order header from the first row
                    AddressInfo billingAddress = new AddressInfo(rdr.GetString(5), rdr.GetString(6), rdr.GetString(7), rdr.GetString(8), rdr.GetString(9), rdr.GetString(10), rdr.GetString(11), rdr.GetString(12), null, "email");
                    AddressInfo shippingAddress = new AddressInfo(rdr.GetString(13), rdr.GetString(14), rdr.GetString(15), rdr.GetString(16), rdr.GetString(17), rdr.GetString(18), rdr.GetString(19), rdr.GetString(20), null, "email");

                    order = new OrderInfo(orderId, rdr.GetDateTime(0), rdr.GetString(1), null, billingAddress, shippingAddress, rdr.GetDecimal(21), null, null);

                    IList<LineItemInfo> lineItems = new List<LineItemInfo>();
                    LineItemInfo item = null;

                    //Create the lineitems from the first row and subsequent rows
                    do {
                        item = new LineItemInfo(rdr.GetString(22), string.Empty, rdr.GetInt32(23), rdr.GetInt32(24), rdr.GetDecimal(25));
                        lineItems.Add(item);
                    } while (rdr.Read());

                    order.LineItems = new LineItemInfo[lineItems.Count];
                    lineItems.CopyTo(order.LineItems, 0);
                }
            }

            return order;
        }

        /// <summary>
        /// Internal function to get cached parameters
        /// </summary>
        /// <returns></returns>
        private static SqlParameter[] GetOrderParameters() {
            SqlParameter[] parms = SqlHelper.GetCachedParameters(SQL_INSERT_ORDER);

            if (parms == null) {
				parms = new SqlParameter[] {
					new SqlParameter(PARM_USER_ID, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_DATE, SqlDbType.DateTime, 12),
					new SqlParameter(PARM_SHIP_ADDRESS1, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_SHIP_ADDRESS2, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_SHIP_CITY, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_SHIP_STATE, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_SHIP_ZIP, SqlDbType.VarChar, 50),
					new SqlParameter(PARM_SHIP_COUNTRY, SqlDbType.VarChar, 50),
					new SqlParameter(PARM_BILL_ADDRESS1, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_BILL_ADDRESS2, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_BILL_CITY, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_BILL_STATE, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_BILL_ZIP, SqlDbType.VarChar, 50),
					new SqlParameter(PARM_BILL_COUNTRY, SqlDbType.VarChar, 50),
					new SqlParameter(PARM_TOTAL, SqlDbType.Decimal, 8),
					new SqlParameter(PARM_BILL_FIRST_NAME, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_BILL_LAST_NAME, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_SHIP_FIRST_NAME, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_SHIP_LAST_NAME, SqlDbType.VarChar, 80),
					new SqlParameter(PARM_AUTHORIZATION_NUMBER, SqlDbType.Int)};

                SqlHelper.CacheParameters(SQL_INSERT_ORDER, parms);
            }

            return parms;
        }

        private static SqlParameter[] GetItemParameters(int i) {
            SqlParameter[] parms = SqlHelper.GetCachedParameters(SQL_INSERT_ITEM + i);

            if (parms == null) {
                parms = new SqlParameter[] {
					new SqlParameter(PARM_LINE_NUMBER + i, SqlDbType.Int, 4),
					new SqlParameter(PARM_ITEM_ID+i, SqlDbType.VarChar, 10),
					new SqlParameter(PARM_QUANTITY+i, SqlDbType.Int, 4),
					new SqlParameter(PARM_PRICE+i, SqlDbType.Decimal, 8)};

                SqlHelper.CacheParameters(SQL_INSERT_ITEM + i, parms);
            }

            return parms;
        }
    }
}


在Orcle中的实现:OracleDAL
Order.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OracleClient;
using System.Text;
using PetShop.Model;
using PetShop.IDAL;
using PetShop.DBUtility;

namespace PetShop.OracleDAL {

    public class Order : IOrder {

        // Static strings
        private const string SQL_GET_ORDERNUM = "SELECT ORDERNUM.NEXTVAL FROM DUAL";
		private const string SQL_INSERT_ORDER = "INSERT INTO Orders VALUES(:OrderId, :UserId, :OrderDate, :ShipAddress1, :ShipAddress2, :ShipCity, :ShipState, :ShipZip, :ShipCountry, :BillAddress1, :BillAddress2, :BillCity, :BillState, :BillZip, :BillCountry, 'UPS', :Total, :BillFirstName, :BillLastName, :ShipFirstName, :ShipLastName, :AuthorizationNumber, 'US_en')";
		private const string SQL_INSERT_STATUS = "INSERT INTO OrderStatus VALUES(:OrderId, 0, sysdate, 'P')";
        private const string SQL_INSERT_ITEM = "INSERT INTO LineItem VALUES(:OrderId{0}, :LineNumber{0}, :ItemId{0}, :Quantity{0}, :Price{0})";
        private const string SQL_SELECT_ORDER = "SELECT o.OrderDate, o.UserId, o.CardType, o.CreditCard, o.ExprDate, o.BillToFirstName, o.BillToLastName, o.BillAddr1, o.BillAddr2, o.BillCity, o.BillState, o.BillZip, o.BillCountry, o.ShipToFirstName, o.ShipToLastName, o.ShipAddr1, o.ShipAddr2, o.ShipCity, o.ShipState, o.ShipZip, o.ShipCountry, o.TotalPrice, l.ItemId, l.LineNum, l.Quantity, l.UnitPrice FROM Orders o, lineitem l WHERE o.OrderId = :OrderId AND o.orderid = l.orderid";
        private const string PARM_USER_ID = ":UserId";
        private const string PARM_DATE = ":OrderDate";
        private const string PARM_SHIP_ADDRESS1 = ":ShipAddress1";
        private const string PARM_SHIP_ADDRESS2 = ":ShipAddress2";
        private const string PARM_SHIP_CITY = ":ShipCity";
        private const string PARM_SHIP_STATE = ":ShipState";
        private const string PARM_SHIP_ZIP = ":ShipZip";
        private const string PARM_SHIP_COUNTRY = ":ShipCountry";
        private const string PARM_BILL_ADDRESS1 = ":BillAddress1";
        private const string PARM_BILL_ADDRESS2 = ":BillAddress2";
        private const string PARM_BILL_CITY = ":BillCity";
        private const string PARM_BILL_STATE = ":BillState";
        private const string PARM_BILL_ZIP = ":BillZip";
        private const string PARM_BILL_COUNTRY = ":BillCountry";
        private const string PARM_TOTAL = ":Total";
        private const string PARM_BILL_FIRST_NAME = ":BillFirstName";
        private const string PARM_BILL_LAST_NAME = ":BillLastName";
        private const string PARM_SHIP_FIRST_NAME = ":ShipFirstName";
        private const string PARM_SHIP_LAST_NAME = ":ShipLastName";	  
		private const string PARM_AUTHORIZATION_NUMBER = ":AuthorizationNumber";
        private const string PARM_ORDER_ID = ":OrderId";
        private const string PARM_LINE_NUMBER = ":LineNumber";
        private const string PARM_ITEM_ID = ":ItemId";
        private const string PARM_QUANTITY = ":Quantity";
        private const string PARM_PRICE = ":Price";

        /// <summary>
        /// With Oracle we can send a PL/SQL block to the database and 
        /// maintain ACID properties for the batch of statements
        /// The benefits with this is that ou increase performance by
        ///		reducing roundtrips to the database
        ///		gurantee that you only use one database connection and hence same construction costs
        ///	However there are limits to statement size which is based on the 
        ///	maximum size of VARCHAR2 parameters (approx 40,000 characters)
        /// </summary>
        /// <param name="order">Order details</param>
        /// <returns>OrderId</returns>
        public void Insert(OrderInfo order) {
            int orderId = 0;

            // Get the parameters
            OracleParameter[] completeOrderParms = null;
            OracleParameter[] orderParms = GetOrderParameters();
            OracleParameter statusParm = new OracleParameter(PARM_ORDER_ID, OracleType.Number);

            // Bind the parameters
            orderParms[1].Value = order.UserId;
            orderParms[2].Value = order.Date;
            orderParms[3].Value = order.ShippingAddress.Address1;
            orderParms[4].Value = order.ShippingAddress.Address2;
            orderParms[5].Value = order.ShippingAddress.City;
            orderParms[6].Value = order.ShippingAddress.State;
            orderParms[7].Value = order.ShippingAddress.Zip;
            orderParms[8].Value = order.ShippingAddress.Country;
            orderParms[9].Value = order.BillingAddress.Address1;
            orderParms[10].Value = order.BillingAddress.Address2;
            orderParms[11].Value = order.BillingAddress.City;
            orderParms[12].Value = order.BillingAddress.State;
            orderParms[13].Value = order.BillingAddress.Zip;
            orderParms[14].Value = order.BillingAddress.Country;
            orderParms[15].Value = order.OrderTotal;
            orderParms[16].Value = order.BillingAddress.FirstName;
            orderParms[17].Value = order.BillingAddress.LastName;
            orderParms[18].Value = order.ShippingAddress.FirstName;
            orderParms[19].Value = order.ShippingAddress.LastName; 
			orderParms[20].Value = order.AuthorizationNumber.Value;

            // Create the connection to the database
            using (OracleConnection conn = new OracleConnection(OracleHelper.ConnectionStringOrderDistributedTransaction)) {

                // Open the database connection
                conn.Open();

                // Get the order id for the order sequence
                orderId = Convert.ToInt32(OracleHelper.ExecuteScalar(conn, CommandType.Text, SQL_GET_ORDERNUM));

                orderParms[0].Value = orderId;
                statusParm.Value = orderId;

                // Total number of parameters = order parameters count + 1 + (5 * number of lines)
                int numberOfParameters = orderParms.Length + 1 + (5 * order.LineItems.Length);

                //Create a set of parameters
                completeOrderParms = new OracleParameter[numberOfParameters];

                //Copy the parameters to the execution parameters
                orderParms.CopyTo(completeOrderParms, 0);
				completeOrderParms[orderParms.Length] = statusParm;

                //Create a batch statement
                StringBuilder finalSQLQuery = new StringBuilder("BEGIN ");

                // Append the order header statements
                finalSQLQuery.Append(SQL_INSERT_ORDER);
                finalSQLQuery.Append("; ");
                finalSQLQuery.Append(SQL_INSERT_STATUS);
                finalSQLQuery.Append("; ");

				int index = orderParms.Length + 1;
                int i = 1;

                // Append each line item to the batch statement
                foreach (LineItemInfo item in order.LineItems) {

                    //Add the appropriate parameters
                    completeOrderParms[index] = new OracleParameter(PARM_ORDER_ID + i, OracleType.Number);
                    completeOrderParms[index++].Value = orderId;
                    completeOrderParms[index] = new OracleParameter(PARM_LINE_NUMBER + i, OracleType.Number);
                    completeOrderParms[index++].Value = item.Line;
                    completeOrderParms[index] = new OracleParameter(PARM_ITEM_ID + i, OracleType.Char, 10);
                    completeOrderParms[index++].Value = item.ItemId;
                    completeOrderParms[index] = new OracleParameter(PARM_QUANTITY + i, OracleType.Number);
                    completeOrderParms[index++].Value = item.Quantity;
                    completeOrderParms[index] = new OracleParameter(PARM_PRICE + i, OracleType.Number);
                    completeOrderParms[index++].Value = item.Price;

                    // Append the statement to the batch
                    finalSQLQuery.Append(string.Format(SQL_INSERT_ITEM, i));
                    finalSQLQuery.Append("; ");
                    i++;

                }

                //Close the PL/SQL block
                finalSQLQuery.Append("END;");

                // Finally execute the query
                OracleHelper.ExecuteNonQuery(conn, CommandType.Text, finalSQLQuery.ToString(), completeOrderParms);
            }


        }

        /// <summary>
        /// Read an order from the database
        /// </summary>
        /// <param name="orderId">Order Id</param>
        /// <returns>Details of the Order</returns>
        public OrderInfo GetOrder(int orderId) {

            //Create a parameter
            OracleParameter parm = new OracleParameter(PARM_ORDER_ID, OracleType.Number);
            parm.Value = orderId;

            //Execute a query to read the order
            using (OracleDataReader rdr = OracleHelper.ExecuteReader(OracleHelper.ConnectionStringOrderDistributedTransaction, CommandType.Text, SQL_SELECT_ORDER, parm)) {
                if (rdr.Read()) {
                    //Generate an order header from the first row
                    AddressInfo billingAddress = new AddressInfo(rdr.GetString(5), rdr.GetString(6), rdr.GetString(7), rdr.GetString(8), rdr.GetString(9), rdr.GetString(10), rdr.GetString(11), rdr.GetString(12), null, "email");
                    AddressInfo shippingAddress = new AddressInfo(rdr.GetString(13), rdr.GetString(14), rdr.GetString(15), rdr.GetString(16), rdr.GetString(17), rdr.GetString(18), rdr.GetString(19), rdr.GetString(20), null, "email");

					OrderInfo order = new OrderInfo(orderId, rdr.GetDateTime(0), rdr.GetString(1), null, billingAddress, shippingAddress, rdr.GetDecimal(21), null, null);

                    IList<LineItemInfo> lineItems = new List<LineItemInfo>();
                    LineItemInfo item = null;

                    //Create the lineitems from the first row and subsequent rows
                    do {
                        item = new LineItemInfo(rdr.GetString(22), string.Empty, rdr.GetInt32(23), rdr.GetInt32(24), rdr.GetDecimal(25));
                        lineItems.Add(item);
                    } while (rdr.Read());

                    order.LineItems = new LineItemInfo[lineItems.Count];
                    lineItems.CopyTo(order.LineItems, 0);

                    return order;
                }
            }

            return null;
        }

        /// <summary>
        /// Internal function to get cached parameters
        /// </summary>
        /// <returns></returns>
        private static OracleParameter[] GetOrderParameters() {
            OracleParameter[] parms = OracleHelper.GetCachedParameters(SQL_INSERT_ORDER);

            if (parms == null) {
                parms = new OracleParameter[] {												 
					new OracleParameter(PARM_ORDER_ID, OracleType.Number, 10),
					new OracleParameter(PARM_USER_ID, OracleType.VarChar, 80),
					new OracleParameter(PARM_DATE, OracleType.DateTime),
					new OracleParameter(PARM_SHIP_ADDRESS1, OracleType.VarChar, 80),
					new OracleParameter(PARM_SHIP_ADDRESS2, OracleType.VarChar, 80),
					new OracleParameter(PARM_SHIP_CITY, OracleType.VarChar, 80),
					new OracleParameter(PARM_SHIP_STATE, OracleType.VarChar, 80),
					new OracleParameter(PARM_SHIP_ZIP, OracleType.VarChar, 50),
					new OracleParameter(PARM_SHIP_COUNTRY, OracleType.VarChar, 50),
					new OracleParameter(PARM_BILL_ADDRESS1, OracleType.VarChar, 80),
					new OracleParameter(PARM_BILL_ADDRESS2, OracleType.VarChar, 80),
					new OracleParameter(PARM_BILL_CITY, OracleType.VarChar, 80),
					new OracleParameter(PARM_BILL_STATE, OracleType.VarChar, 80),
					new OracleParameter(PARM_BILL_ZIP, OracleType.VarChar, 50),
					new OracleParameter(PARM_BILL_COUNTRY, OracleType.VarChar, 50),
					new OracleParameter(PARM_TOTAL, OracleType.Number),
					new OracleParameter(PARM_BILL_FIRST_NAME, OracleType.VarChar, 80),
					new OracleParameter(PARM_BILL_LAST_NAME, OracleType.VarChar, 80),
					new OracleParameter(PARM_SHIP_FIRST_NAME, OracleType.VarChar, 80),
					new OracleParameter(PARM_SHIP_LAST_NAME, OracleType.VarChar, 80),
				    new OracleParameter(PARM_AUTHORIZATION_NUMBER, OracleType.Int32)};

                OracleHelper.CacheParameters(SQL_INSERT_ORDER, parms);
            }

            return parms;
        }
    }
}


总结:
虽然没有完全按照GOF的抽象工厂模式去定义,但是其实现思想是一样的。
算是一种变种。
DataAcess代码可以进行变种,如将这些方法都抽象出来
public  PetShop.IDAL.ICategory CreateCategory()
IDataAccess接口,然后,实现DataAccessSql,DataAccessOracle,再过去配置文件创建出来。如果这样,那就过于为了模式而模式。比较僵。



2011-6-23 15:50 danny
分享到:
评论

相关推荐

    C#抽象工厂模式案例代码

    工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。

    java设计模式-抽象工厂模式

    java,设计模式中的一种,抽象工厂设计模式。

    设计模式_抽象工厂模式.zip

    这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。 抽象工厂模式...

    抽象工厂模式(Abstract Factory Pattern)

    咱们假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在你的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然...

    抽象工厂模式 源代码

    如何绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式。 意图 提供一个创建一系列相关或相互依赖对象的接口,而...

    抽象工厂模式

    抽象工厂模式 是一种软件开发设计模式。抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。在正常使用中,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题...

    抽象工厂实现访问多多种数据库

    用一个简单的小例子 实现抽象工厂设计模式 采用面向对象思想编程 程序实现了MyShool的一个简单的添加学员的功能 采用抽象工厂实现程序支持访问多数据库(Access和SQL)...详细见资料

    基于抽象工厂模式的塑料加工厂(java).zip

    项目需求: 有两间塑料加工厂(A厂仅生产容器类产品;B厂仅生产模具类产品);... 抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。

    设计模式:单例设计模式(全部实现方式)工厂设计模式,抽象工厂模式

    抽象工厂模式是一种创建型设计模式,它的主要目标是提供一个接口或抽象类,用于创建一系列相关或依赖的对象。该模式的主要优点在于,它可以为客户端代码提供一个统一的接口,使得客户端无需关心具体实现细节。抽象...

    抽象工厂模式(Abstract Factory).doc

    在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象的创建方法(new),...这就是我们要说的抽象工厂模式。

    抽象工厂模式更换UI皮肤设计模式作业(100分)

    抽象工厂模式是一种创建型设计模式,它提供了一种将相关的对象家族分组创建的方式,而无需指定具体类。在该模式中,我们定义一个抽象工厂接口,该接口声明了一组创建不同类型对象的方法。每个具体工厂都实现了这个...

    23种设计模式之抽象工厂模式Java示例代码

    抽象工厂模式为创建一组相关或相互依赖的对象提供了一个接口,而不需要指定它们的具体类。本文适合对设计模式和Java编程语言感兴趣的读者学习和参考。 使用人群:软件开发工程师、Java程序员、架构师、设计模式爱好...

    05_C_设计模式-抽象工厂模式

    他是一种模式,计算机软件开发的一种模式,可以兼容多个数据库,以及数据库之间交互

    抽象工厂模式习题源代码

    (1)请使用抽象工厂模式设计系统 (2)为系统增加一种新的主题,并实现 (3)如果当系统主题发生变化的时候通讯录风格也发生变化,在这种情况之下上面设计的系统将如何变化? (4)(2)和(3)的结论说明了什么?

    PHP实现设计模式中的抽象工厂模式详解

    抽象工厂模式(Abstact Factory)是一种常见的软件设计模式。该模式为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以为此系列的产品族创建一个 具体的工厂类。 【意图】 抽象工厂模式提供...

    python 抽象工厂模式(示例)

    这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。# 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

    C# asp.net抽象工厂 简单登录页

    对于初学者来说,理解和掌握一种设计模式,并非易事,网上有些复杂点的程序,看懂和理解需要很长的时间,这个简单的抽象工厂练习,希望能帮助初学者了解抽象工厂并且在VS中配置它。当然本人能力有限,有不合理的地方...

    设计模式(十六)之抽象工厂模式.zip

    这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

    抽象工厂视频

    抽象工厂视频学习基础,学习java设计模式基础企业单位都需要用到的一种模式

Global site tag (gtag.js) - Google Analytics