博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式——抽象工厂模式(Abstract Factory)

Posted on 2008-08-20 11:11  Anna Yang  阅读(861)  评论(3编辑  收藏  举报

设计模式(3): 抽象工厂模式(Abstract Factory)  

 

抽象工厂模式(Abstract Factory)

 
概述
 
    抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类. 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式。提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式(abstract Factory)结构图
 
以“新增用户”和“得到用户”为例。用户类,假设只有ID和Name两个字段 
Code
 
常规做法:
Code
 
客户端代码: 
Code
 
若要增加一个数据库Access 就会很那麻烦。在此运用抽象工厂模式: 
 
添加IUser接口,用于客户端访问,解除与具体数据库访问的耦合
interface IUser
{
    
void insert(User user);
    User GetUser(
int id);
}
 
SqlserverUser类,用于访问SQL Server的User
class SqlserverUser:IUser
{
    
public void Insert(User user)
    {
        Console.WriteLine(
"在SQL Server中给User表增加一条记录");
    }
    
public User GetUser(int id)
    {
        Console.WriteLine(
"在SQL Server中根据ID得到User表一条记录");
        
return null;
    }
}
 
AccessUser类,用于访问Access的User
class AccessUser:IUser
{
    
public void Insert(User user)
    {
        Console.WriteLine(
"在Access中给User表增加一条记录");
    }
    
public User getUser(int id)
    {
        Console.WriteLine(
"在Access中根据ID得到User表一条记录");
        
return null;
    }
}
 
 IFactory接口,定义一个创建访问User表对象的抽象的工厂接口。 
 interface IFactory
{
    IUser CreateUser();
}
 
SqlserverFactory类,实现IFactory接口,实例化SqlserverUser。 
class SqlserverFactory:IFactory
{
    
public IUser CreateUser()
    {
        
return new SqlserverUser();
    }
}
 
AccessFactory类,实现IFactory接口,实例化AccessUser/ 
class AccessFactory:IFactory
{
    
public IUser CreateUser()
    {
        
return new AccessUser();
    }
 
抽象工厂模式客户端代码: 
static void Main(string[] args)
{
    User user
=new User();
    IFactory factory
=new SqlserverFctory();
    
//IFactory factory=new AccessFctory();
    IUser iu=factory.CreateUser();
    iu.Insert(user);
    iu.GetUser(
1);
}
用DataAccess类代替IFatory ,sqlserverFactory和AccessFactiry三个工厂类 
 
class DataAccess
{
    
private static readonly string db="Sqlserver";
    
//private static readonly string db="Access";
    public static IUser CreateUser()
    {
        IUser result
=null;
       swith(db)
       {
         
case"Sqlserver":
             result
=new SqlserverUser();
             
return result;
             
break;
         
case"Access":
             result
=new AccessUser();
             
return result;
             
break;
        }
    
return result;
    }
}
 
客户端代码: 
static void Main()
{
    User user
=new User();
    IUser iu
=DataAccess.CreateUser();
    iu.Insert(user);
    iu.Getuser(
1);
}
 
运用反射对DataAccess进行改进,消除swith:
反射技术的格式:Assembly.Load("程序集名称").CreateInstance("命名空间.类名称") 
using System.Reflection;
class DataAccess
{
    
private static readonly string AssemblyName="抽象工厂模式";
    
private static readonly string db="Sqlserver";
//    private static readonly string db="Access";

    
public static IUser CreateUser()
    {
        
string className=Assembly+"."+db+"User";     
        
return (IUser)Assembly.load(AssemblyName).CreateInstance(className); //运用反射
    }
}
 
客户端代码
static void Main(string[] args)
{
    User user
=new User();
    Iuer iu
=DataAccess.CreateUser();
    iu.insert(user);
    iu.GetUser(
1);
    Console.Read();
}