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

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

  简单的工厂类的一个使用场景是, 假设有一个基类 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(FactoryK
eyAttribute
)) 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 的类型参数即可。

目录
相关文章
|
7月前
|
存储 关系型数据库 数据中心
每日一博 - CRUD system VS Event sourcing design
每日一博 - CRUD system VS Event sourcing design
22 0
|
设计模式 PHP
php设计模式-简单工厂模式 (Simple Factory)
简单工厂模式又称为静态工厂方法模型,它属于类创建型模式,简单工厂并不属于23种设计模式,刚开始学习设计模式的同学,对简单工厂模式、工厂方法、抽象工厂中的工厂一知半解,其实白话点来说:这些模式一定会有一个工厂类,子类并不需要知道工厂细节,只需新建工厂创建产品即好。
101 0
|
安全 Java
java常用类之System
System是一个类,这个System类主要是一些与系统相关的属性和方法的集合,而且其内部的方法全部是静态的,所以我们直接使用System直接调用就好,比如我们常用的一个System.out.print。这篇文章我们就来分析一下System类。
286 0
java常用类之System
|
监控 .NET
艾伟_转载:.NET设计模式:工厂方法模式(Factory Method)
  概述   在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?提供一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变?这就是要说的Factory Method模式了。
818 0
艾伟:[WCF的Binding模型]之四:信道工厂(Channel Factory)
由于信道管理器在客户端和服务端所起的不同作用,分为信道监听器和信道工厂。和服务端的信道监听其相比,处于客户端的信道工厂显得简单。从名称就可以看得出来,信道工厂的作用就是单纯的创建用于消息发送的信道。我们先来看看与信道工厂相关的一些接口和基类的定义。
1062 0
|
C#
艾伟:C# Design Patterns (1) - Factory Method
Simple Factory Pattern (简单工厂模式) 特性: 把类的实例化工作,集中到一个「工厂类」去处理,亦即将 new instance 的工作,都交给一个「工厂」去处理,而不要分散写在各个类中。
861 0
|
C#
艾伟_转载:C# Design Patterns (1) - Factory Method
Simple Factory Pattern (简单工厂模式) 特性: 把类的实例化工作,集中到一个「工厂类」去处理,亦即将 new instance 的工作,都交给一个「工厂」去处理,而不要分散写在各个类中。
942 0
|
存储 缓存 弹性计算
Unity Entity Component System 理论知识总结
今天跟同学们分享一下我找到的关于ECS相关的理论知识文章,可能比较枯燥,如果想看实操的请看我下方写的一些案例解析。 Unity之浅析 Entity Component System (ECS) Unity 之 Pure版Entity Compon...
1948 0
|
C# 设计模式 .NET
使用C# (.NET Core) 实现简单工厂(Simple Factory) 和工厂方法设计模式 (Factory Method Pattern)
本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子.   前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是接口(interface).
1404 0