艾伟_转载:一个简单的 Generic Factory 类

  简单的工厂类的一个使用场景是, 假设有一个基类 BaseClass, 和一系列的子类 A, B, C, 工厂类根据某个参数,例如字符串 “A”, “B”, “C” 创建出相应的子类。 举例如下:

public class Factory
{
    public static BaseClass Create(string name)
    {
        switch (name)
        {
            case "A": return new A();
            case "B": return new B();
            case "C": return new C();
            default: throw new ArgumentException("Wrong Name");
        }
    }
}

  这里的一个问题是, 当子类增加或减少时, Factory 类 需要相应的改动。 有没有办法可以只是改动子类本身, 而不用修改Factory类呢, 当然有,这里我举一个简单的实现。

  基本思想是在每个子类上附加一个 Attribute, 定义如下:

[AttributeUsage(AttributeTargets.Class)]
public class FactoryKeyAttribute : Attribute
{
    public object Key { get; set; }
}

  假设我们有基类和子类实现如下

public abstract class BaseClass {}
[FactoryKey(Key = "Standard")]
public class Standard : BaseClass {}
[FactoryKey(Key = "Enterprise")]
public class Enterprise : BaseClass {}
[FactoryKey(Key = "Lite")]
public class Lite : BaseClass {}

 

  假设这些类都在同一个 Assembly中 (对于不在同一个Assembly的,实现会稍微复杂些)工厂类需要预先加载 Key => Type 的Mapping, 然后根据Key创建不同的实例, 实现如下:

public static class Factory<TKey, TBaseClass>
{
    private static readonly IDictionary<TKey, Type> TypeDict = Init();
    private static IDictionary<TKey, Type> Init()
    {
        var dict = from type in Assembly.GetExecutingAssembly().GetTypes()
                   let key = (FactoryKeyAttribute)Attribute.GetCustomAttribute(type, typeof(FactoryKeyAttribute))
                   where key != null && type.IsSubclassOf(typeof(TBaseClass))
                   select new { Key = key, Value = type };
        return dict.ToDictionary(kvp => (TKey)kvp.Key.Key, kvp => kvp.Value);
    }
    public static TBaseClass CreateInstance(TKey key)
    {
        Type type;
        if (TypeDict.TryGetValue(key, out type))
        {
            return (TBaseClass)Activator.CreateInstance(type);
        }
        throw new ArgumentException("Incorrect Key!");
    }
}

  使用方法也很简单:

BaseClass s = Factory<string, BaseClass>.CreateInstance("Standard");
BaseClass l = Factory<string, BaseClass>.CreateInstance("Lite");
BaseClass e = Factory<string, BaseClass>.CreateInstance("Enterprise");

 

  对于其他类型的Key,比如 Enum, 或其他类型的基类, 改变Factory 的类型参数即可。

时间: 2024-07-31 10:53:30

艾伟_转载:一个简单的 Generic Factory 类的相关文章

一个简单的Generic Factory类

简单的工厂类的一个使用场景是,假设有一个基类 BaseClass,和一系列的子类 A,B,C,工厂类根据某个参数,例如字符串 "A", "B", "C" 创建出相应的子类. 举例如下: public class Factory { public static BaseClass Create(string name) { switch (name) { case "A": return new A(); case "

艾伟_转载:简单的自动更新程序实现

本文将演示一种桌面程序自动更新方案,其步骤比较多,但原理非常简单,通用性尚可,对于小型应用来说,直接拿去就可以用了. 原理 服务器端的结构是这样的: 其工作原理如下: Update.asmx仅提供一个功能,就是检测是否需要更新,在需要更新的时候就返回一个更新地址,通常情况下返回的地址就是Download.ashx,而在某些特殊情况下,也可以修改服务端使之从其他Url提供更新下载.检测是否需要更新的的具体做法是:首先获取Updata目录中的主程序版本号,再获取数据库中的最新版本号,两者对比.如果相

艾伟_转载:Socket开发探秘--基类及公共类的定义

Socket开发是属于通信底层的开发,.NET也提供了非常丰富的类来实现Socket的开发工作,本篇不是介绍这些基础类的操作,而是从一个大的架构方面阐述Socket的快速开发工作,本篇以TCP模式进行程序的开发介绍,以期达到抛砖引玉的目的. 要掌握或者了解Socket开发,必须了解下面所述的场景及知识. 1.TCP客户端,连接服务器端,进行数据通信 2.TCP服务器端,负责侦听客户端连接 3.连接客户端的管理,如登陆,注销等,使用独立线程处理 4.数据接收管理,负责数据的接受,并处理队列的分发,

PHP实现的一个简单的数据库操作类

PHP实现的一个简单的数据库操作类 实现的功能: - 在实例化的时候能设置连接字符集 - 在实例化的时候能连接数据库 - 在实例化的时候能选择默认数据库 - 销毁对象时关闭数据库 代码如下: <?php // 数据库操作类MySQLDB class MySQLDB { // 声明属性 private $server; private $username; private $password; public $default_db; public $link; // 声明构造函数 public f

艾伟_转载:.NET设计模式:抽象工厂模式(Abstract Factory)

概述 在软件系统中,经常面临着"一系列相互依赖的对象"的创建工作:同时由于需求的变化,往往存在着更多系列对象的创建工作.如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种"封装机制"来避免客户程序和这种"多系列具体对象创建工作"的紧耦合?这就是我们要说的抽象工厂模式. 意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 模型图 逻辑模型: 物理模型: 生活中的例子 抽象工厂的目的是要提供一个创建一系列相关或

艾伟_转载:WCF版的PetShop之三:实现分布式的Membership和上下文传递

本系列文章导航 WCF版的PetShop之一:PetShop简介 WCF版的PetShop之二:模块中的层次划分 WCF版的PetShop之三:实现分布式的Membership和上下文传递 通过上一篇了解了模块内基本的层次划分之后,接下来我们来聊聊PetShop中一些基本基础功能的实现,以及一些设计.架构上的应用如何同WCF进行集成.本篇讨论两个问题:实现分布式的Membership和客户端到服务端上下文(Context)的传递. 一. 如何实现用户验证 对登录用户的验证是大部分应用所必需的,对

艾伟_转载:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现

在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高级语言更多的CLR细节.因此,如果您想要通过学习IL来了解CLR,那么这个过程很可能会"事倍功半".因此,从这个角度来说,老赵并不倾向于学习IL.不过严格说来,即使IL无法看出CLR的细节,也不足以说明"IL无用"--这里说"无用"自然有些夸张.但是

艾伟_转载:WCF版的PetShop之一:PetShop简介

本系列文章导航 WCF版的PetShop之一:PetShop简介 WCF版的PetShop之二:模块中的层次划分 WCF版的PetShop之三:实现分布式的Membership和上下文传递 在<WCF技术剖析(卷1)>的最后一章,我写了一个简单基于WCF的Web应用程序,该程序模拟一个最简单的网上订购的场景,所以我将其命名为PetShop.PetShop的目在于让读者体会到在真正的项目开发中,如何正确地.有效地使用WCF.在这个应用中,还会将个人对设计的一些总结融入其中,希望能够对读者有所启发

艾伟_转载:LINQ to SQL、NHibernate比较(二)-- LINQ to SQL实例

    用ADO.NET操作数据库大家一定再熟悉不过了,select.insert.update等等SQL语句大家也都必然滚瓜烂熟.我将自己在学习LINQ to SQL过程中的动手经历记录下来,作为今后学习的参考,也希望对刚刚接触的人有一点帮助.     我在本文涉及到一个很简单的系统,利用DataGridView实现数据库数据的批量增.删.改,不是什么强大的功能.     如果有人感兴趣,可以在看完我的这篇文章之后用ADO.NET实现同样的功能,看看到底会比使用LINQ to SQL多多少时间