zoukankan      html  css  js  c++  java
  • Net设计模式实例之抽象工厂模式(Abstract Factory Pattern)

    一、抽象工厂模式简介(Bref Introduction

    抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类。优点是:易于交换产品系列,由于具体工厂类在一个应该用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂类变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。抽象工厂的另一个优点是,它让具体的创建实例与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户的代码中。

    二、解决的问题(What To Solve

           常用用于解决数据访问程序,也就是说程序通过使用抽象工厂模式后,可以灵活地在不同的数据库之间切换,而不需要费时费力地改变原有程序。

    三、抽象工厂模式分析(Analysis

    1、抽象工厂模式结构

     

    IProductAIProductA接口:两个产品接口,他们都有可能有两种不同的实现。

    ProductA1ProductA2ProductB1ProductB2具体实现类:对两个产品接口的具体分类的实现。

    AbstractFactory抽象类:抽象工厂接口,它里面应该包含所有产品创建的抽象方法。

    ConcreteFactory1ConcreteFactory2具体工厂类:创建具有特定实现的产品对象

    2、源代码

    1、产品接口IProductAIProductB及其两种实现

    public interface IProductA

    {

        void Show();

    }

     

    public class ProductA1 : IProductA

    {

        public void Show()

        {

            Console.WriteLine("具体产品类{0}展示方法。",this.GetType().Name);

        }

    }

     

    public class ProductA2 : IProductA

    {

        public void Show()

        {

            Console.WriteLine("具体产品类{0}展示方法。", this.GetType().Name);

        }

    }

     

    public interface IProductB

    {

        void Insert();

    }

     

    public class ProductB1 : IProductB

    {

        public void Insert()

        {

            Console.WriteLine("具体产品类{0}插入方法。", this.GetType().Name);

        }

    }

     

    public class ProductB2 : IProductB

    {

        public void Insert()

        {

            Console.WriteLine("具体产品类{0}插入方法。", this.GetType().Name);

        }

    }

     

    2抽象工厂接口AbstractFactory,及其具体的工厂AbstractFactory1AbstractFactory2

    public abstract class AbstractFactory

    {

        public abstract IProductA CreateProductA();

        public abstract IProductB CreateProductB();

    }

     

    public class AbstractFactory1:AbstractFactory

    {

     

        public override IProductA CreateProductA()

        {

            IProductA productA1 = new ProductA1();

            return productA1;

        }

     

        public override IProductB CreateProductB()

        {

            IProductB productB1 = new ProductB1();

            return productB1;

        }

    }

     

    public class AbstractFactory2 : AbstractFactory

    {

     

        public override IProductA CreateProductA()

        {

            IProductA productA2 = new ProductA2();

            return productA2;

        }

     

        public override IProductB CreateProductB()

        {

            IProductB productB2 = new ProductB2();

            return productB2;

        }

    }

     

    3、客户端代码

    static void Main(string[] args)

    {

        //根据需求调用具体工厂AbstractFactory1

        AbstractFactory factory1 = new AbstractFactory1();

        IProductA productA1 = factory1.CreateProductA();

        IProductB productB1 = factory1.CreateProductB();

        productA1.Show();

        productB1.Insert();

        Console.WriteLine("\n");

        //根据需求调用具体工厂AbstractFactory2

        AbstractFactory factory2 = new AbstractFactory2();

        IProductA productA2 = factory2.CreateProductA();

        IProductB productB2 = factory2.CreateProductB();

        productA2.Show();

        productB2.Insert();

     

        Console.ReadKey();

    }

    3、程序运行结果

    四.案例分析(Example

    1、场景

    使用抽象工厂+反射+配置文件实现数据访问层程序。结构如下图所示

     

    用反射+抽象工厂+配置文件的数据访问程序。

    Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")。比如:

    IProduct product=(IProduct)Assembly.Load("抽象工程模式").CreateInstance("抽象工程模式.SqlServerProduct")

    常用做法是:

    Private static readonly string AssemblyName="抽象工程模式";

    Private static readonly string DB=ConfiurationManager.AppSettings["db"];

    配置文件如下:

    <configuration>

        <appSettings>

             <add key="db" value="Sqlserver"/>

        <appSettings>

    <configuration>

    通过读配置文件给DB字符赋值,在配置文件中写明当前使用的是SqlServer 还是Access数据库。反射+抽象工厂+配置文件解决方案解决了数据访问时的可维护、可扩展问题

     

    2、代码

    1、对象UerProduct及其相对应的操作

    public interface IUser

    {

        void Insert();

    }

     

    public class SqlServerUser:IUser

    {

        public void Insert()

        {

            Console.WriteLine("{0}插入用户.",this.GetType().Name);

        }

    }

     

    public class AccessUser : IUser

    {

        public void Insert()

        {

            Console.WriteLine("{0}插入用户.", this.GetType().Name);

        }

    }

     

    public interface IProduct

    {

        void GetProduct();

    }

     

    public class SqlServerProduct : IProduct

    {

        public void GetProduct()

        {

            Console.WriteLine("{0}查询商品.", this.GetType().Name);

        }

    }

     

    public class AccessProduct : IProduct

    {

        public void GetProduct()

        {

            Console.WriteLine("{0}查询商品.", this.GetType().Name);

        }

    }

     

    2、数据访问类DataAccess

    public class DataAccess

    {

        private static readonly string AssemblyName = "AbstractFactoryReflection";

        private static readonly string db = "SqlServer";

     

        public static IUser CreateUser()

        {

            string className = AssemblyName + "." + db + "User";

            IUser user = (IUser)Assembly.Load(AssemblyName).CreateInstance(className);

            return user;

        }

     

        public static IProduct CreateProduct()

        {

            string className = AssemblyName + "." + db + "Product";

            return (IProduct)Assembly.Load(AssemblyName).CreateInstance(className);

        }

    }

     

    3、客户端代码

    static void Main(string[] args)

    {

        IUser user = DataAccess.CreateUser();

        user.Insert();

     

        IProduct product = DataAccess.CreateProduct();

        product.GetProduct();

     

        Console.ReadKey();

    }

     

    五、总结(Summary

    抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类。抽象工厂模式的典型应用就是,使用抽象工厂+反射+配置文件实现数据访问层程序。

  • 相关阅读:
    web项目的集成测试:模拟点击
    ignite通过注解配置查询
    log4j打印出线程号和方法名
    函数
    C语言函数的概念
    C语言字符串的输入输出
    C语言字符串处理函数
    C语言字符数组和字符串
    说说M451例程之PWM的寄存器讲解
    如何给地址赋值?(转)
  • 原文地址:https://www.cnblogs.com/ywqu/p/1641825.html
Copyright © 2011-2022 走看看