1

考虑以下为记录操作而设计的体系结构Add/Update正在Entity.

LogFactory是一个并通过构造函数Abstract Factory接收两个工厂。混凝土工厂和实施都是为了生产. 他们都需要收集可记录的数据。好吧,我希望一切都清楚,并且您承认到目前为止,模式是正确的解决方案。AddUpdateDIAddLogFactoryUpdateLogFactoryILogFactoryILogEntityAbstract Factory

在此处输入图像描述

问题:

UpdateLogFactory是一个例外,因为它需要额外的数据:ModifiedProperties创建一个之前/之后的字符串(同时它的兄弟,即实现的其他类型ILogFactory不需要这种数据;一个Entity就足够了)。为了不破坏ILogFactory,我决定通过它的构造函数ModifiedProperties给予。UpdateLogFactory它解决了我的问题,但我觉得我在作弊;我假装UpdateLogFactory和别人相似,其实不然。

如果有人想UpdateLogFactory用另一种具体类型替换,他怎么知道它需要ModifiedProperties

4

2 回答 2

2

Actually ModifiedProperties is an implementation detail. Do any ILogFactory need to produce that before and after format? I don't think so.

Anyway, I believe that ModifiedProperties shouldn't be injected but they should be part of an interface like ICanTrackPropertyChanges:

public interface ICanTrackPropertyChanges
{
      IEnumerable<string> ModifiedPropertyNames { get; }
}

And ICanTrackPropertyChanges should be implemented by your entities. Thus, UpdateLogFactory can make the following assertion:

ICanTrackPropertyChanges trackable = entity as ICanTrackPropertyChanges;

// Design by contract wins!
Contract.Assert(trackable != null);

// And now access trackable.ModifiedProperties and produce the 
// customized message for entity updates

This way, you don't need to provide ModifiedProperties as an implementation detail of ILogFactory, but you believe that entities can track property changes if they implement an interface.

You can enforce this using generic constraints:

public interface IUpdateLogFactory<TEntity> : ILogFactory
    where TEntity : class, ICanTrackPropertyChanges
{
}

...and use this interface to implement loggeable entity updates.

In addition, you get an improvement: IUpdateLogFactory<TEntity> implementations won't need to check if an entity has ModifiedProperty because handled entities are guaranteed to has the whole IEnumerable<string> of modified properties at compile time!

于 2015-06-20T12:37:48.603 回答
0

您是否混淆了抽象工厂和工厂方法?

您的图表不是 GoF 定义的抽象工厂:

抽象工厂 GoF

你错过了:

  • 两个或多个抽象产品类型(A、B)
  • 两个或多个 createProduct 方法(A、B)。

如果您要将模式应用于您的问题,您将能够在createUpdateLog方法上使用额外的参数(如下所示),但是您将遇到几个不适合的类的问题(以粉红色表示):

本上下文中抽象工厂的PlantUML图

我怀疑您正在尝试使用只有一个签名的工厂方法模式,这就是为什么您在 s 的情况下遇到“异常”参数的原因UpdateLog

编辑

这是工厂方法模式

GoF 的工厂方法模式

如您所见,每个混凝土工厂只处理一种混凝土产品。

现在我将把你的设计从问题插入到这个模式:

应用工厂方法

于 2015-06-21T02:01:58.573 回答