我已经在我的项目中实现了一个工厂,最近有人建议我在我的类上使用属性,这样工厂就可以确定实例化哪个类并传回。我是开发领域的新手,试图严格遵循松耦合规则,我想知道依赖“钩子”(属性)是否与此背道而驰?
发布于 2010-12-08 21:05:41
我不认为使用属性会增加工厂和它创建的类之间的耦合度,事实上,它会减少这里的耦合度,因为工厂会在运行时通过属性发现信息。如果有什么不同的话,那就是简单地交换为耦合到属性而创建的类之间的耦合。也就是说,我不确定这到底能为你买到什么。工厂的要点是将创建逻辑本地化在一个地方。通过将其放入属性中,您再次将其散布到代码中,这在一定程度上违背了工厂的目的:现在,您必须同时查看工厂和属性,以了解对象是如何创建的。
当然,我可能误解了你的问题。您的意思可能是,一个类使用其属性上的属性来指示哪些属性需要由工厂实例化。在这种情况下,您将替换一些用于进行依赖注入的配置驱动机制。我当然可以看到这可能有用的地方;让工厂发现对象的依赖关系,并在运行时自动创建它们。在这种情况下,您将略微增加代码的整体耦合性,因为现在属性和工厂之间存在以前不存在的依赖关系。总体而言,您可能会降低代码复杂性,因为您不需要为每个类编写特定的代码来提供其特定的依赖项或从配置文件中发现它们。
如果你问使用属性是否是一个好主意,我想我们可能需要更多的信息,但既然你似乎只问你是否会违反OO原则,我不这么认为。我不认为它会增加工厂和要创建的类之间的耦合,而只是略微增加代码的整体耦合。工厂本质上比其他类需要更多的耦合。记住,它是松耦合的,而不是解耦的。未耦合的代码不会做任何事情。您需要类之间的关系才能使任何事情发生。
发布于 2010-12-08 21:05:59
装饰工厂的产品类可以使开发变得更容易,这是我有时会做的事情。例如,当必须基于存储在数据库中的唯一标识符来创建产品时,这尤其有用。在这个唯一的id和product类之间必须有一个映射,使用一个属性可以使这个映射变得非常清晰和可靠。除此之外,它还允许您添加产品类,而无需更改工厂。
例如,你可以这样装饰你的类:
[ProductAttribute(1)]
public class MyFirstProduct : IProduct
{
}
[ProductAttribute(2)]
public class MySecondProduct : IProduct
{
}
你可以像这样实现你的工厂:
public class ProductFactory : IProductFactory
{
private static Dictionary<int, Type> products =
new Dictionary<int, Type>();
static ProductFactory()
{
// Please note that this query is a bit simplistic. It doesn't
// handle error reporting.
var productsWithId =
from type in
Assembly.GetExecutingAssembly().GetTypes()
where typeof(IProduct).IsAssignableFrom(type)
where !type.IsAbstract && !type.IsInterface
let attributes = type.GetCustomAttributes(
typeof(ProductAttribute), false)
let attribute = attributes[0] as ProductAttribute
select new { type, attribute.Id };
products = productsWithId
.ToDictionary(p => p.Id, p => p.type);
}
public IProduct CreateInstanceById(int id)
{
Type productType = products[id];
return Activator.CreateInstance(productType) as IProduct;
}
}
这样做之后,您可以使用该工厂来创建产品,如下所示:
private IProductFactory factory;
public void SellProducts(IEnumerable<int> productIds)
{
IEnumerable<IProduct> products =
from productId in productIds
select factory.CreateInstanceById(productId);
foreach (var product in products)
{
product.Sell();
}
}
例如,我过去使用过这个概念来创建基于数据库标识符的发票计算。该数据库包含每种发票类型的计算列表。实际计算是在C#类中定义的。
发布于 2013-03-28 23:18:51
下面是我用来基于属性值创建具体实例的工厂实现。它还使用参数实例化。
class ViewFactory
{
public static IView GetViewType(string PropertyValue, SomeOtherObject parentControl){
Assembly assembly = Assembly.GetAssembly(typeof(ViewFactory));
var types = from type in assembly.GetTypes()
where Attribute.IsDefined(type,typeof(ViewTypeAttribute))
select type;
var objectType = types.Select(p => p).
Where(t => t.GetCustomAttributes(typeof(ViewTypeAttribute), false)
.Any(att => ((ViewTypeAttribute)att).name.Equals(PropertyValue)));
IView myObject = (IView)Activator.CreateInstance(objectType.First(),parentControl);
return myObject;
}
}
[ViewTypeAttribute("PropertyValue", "1.0")]
class ListboxView : IView
{
public ListboxView(FilterDocumentChoseTypeFieldControll parentControl)
{
}
public override void CreateChildrens()
{
}
}
https://stackoverflow.com/questions/4387573
复制相似问题