gpt4 book ai didi

c# - 这段代码中的设计模式是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 20:41:58 24 4
gpt4 key购买 nike

假设我有一个单例类、工厂类、反射类,它接收一些输入,并吐回某个接口(interface)的具体实现的新实例。这是怎样的设计?有没有更好的方法来做我想做的事?

下面是一些代码来说明这一点:

using System;
using System.Collections.Generic;

// static factory class
public static class ArticleFactory
{
// given an SKU, store the Type object for an IArticle object
private static Dictionary<string, Type> articleRegistry = new Dictionary<string, Type>();

// allow public registration of SKU-to-Type object relationships
public static bool Register(string sku, Type typeInfo)
{
if(!articleRegistry.ContainsKey(sku))
{
articleRegistry.Add(sku, typeInfo);
return true;
}
return false;
}

// given a SKU, give me an instance of the related IArticle object
public static IArticle NewArticle(string sku)
{
if(articleRegistry.ContainsKey(sku))
{
// use reflection to invoke the default constructor
return articleRegistry[sku].GetConstructor(Types.EmptyTypes).Invoke(null) as IArticle;
}
return null;
}
}

// example concrete-implementation of an IArticle
public class Jeans : IArticle
{
public decimal GetPrice() { return SomeDecimal(); }
}

// WHERE DO I CALL THIS LINE?
ArticleFactory.Register("0929-291", typeof(Jeans));

// Later on, if another group needs to write the class for Snowboards,
// how can they self-register their class, without changing any "Main()"
// or "Page_Init()" function?

最佳答案

看起来您已经确定了模式。这是 Factory Method Pattern .或者更确切地说,一个有点半生不熟的实现。一个稍微好一点的方法是首先使它成为一个接口(interface):

public interface IArticleFactory
{
IArticle CreateArticle(string sku);
}

然后在没有任何反射的情况下实现工厂:

public class MyArticleFactory
{
private Dictionary<string, Func<IArticle>> instantiators =
new Dictionary<string, Func<Iarticle>>();

public MyArticleFactory()
{
Register("Jeans", () => new Jeans());
Register("Shirt", () => new Shirt());
// etc.
}

public IArticle CreateArticle(string sku)
{
Func<IArticle> instantiator;
if (creators.TryGetValue(sku, out instantiator))
return instantiator();
throw new UnknownSkuException(sku);
}

protected void Register(string sku, Func<IArticle> instantiator)
{
creators.Add(sku, instantiator);
}
}

几个重要的区别:

  • 注册不公开,也不应该公开。注册通常驻留在某处的配置文件中或者是私有(private)的。

  • 不要求 IArticle 具体类型具有默认的无参数构造函数。这可以很容易地注册带有参数化构造函数的文章(只要它知道要使用什么参数)。

  • 对重复注册抛出异常。我不喜欢简单地返回 false 的想法;如果您尝试注册同一个工厂方法两次,那应该被认为是一个错误。

  • 它不是静态的。您可以将此工厂替换为其他工厂。您可以对其进行单元测试。

当然,更好的方法是使用任何现有的 .NET 依赖注入(inject)/控制反转框架,例如 NinjectAutoFac .

关于c# - 这段代码中的设计模式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2249723/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com