LogEvent表示日志级别,消息,用户,进程名称等信息...... 其中一些属性'价值需要相当大的努力才能产生,例如: G。进程名称。那些属性'生成的值通常没有改变,但尽管如此,应该可以更改它们。
我认为原型模式以protoype开头,其泛型属性是预先分配的。原型在应用程序的生命周期内保持相同的对象,但其属性为'值可能会如上所述发生变化。新的LogEvent对象应使用当前原型的值,在更改之前使用旧值继续创建的对象,这意味着,引用来自" real" LogEvent对象不是一个选项。
然而,"真实" LogEvent要求某些属性不为null,而此要求对原型无用。我想防止LogEvent的无效对象。但是,如果我使用通常的原型模式,我将不得不添加一个构造函数来创建原型,但是这个构造函数不会创建一个有效的对象,我想避免使用无效的对象(原型本身或它的克隆)意外。我花了一些时间来搜索解决方案,但下面列出的方法非常难看。我希望,有一个优雅的解决方案。同时我倾向于选择3,因为1和2看起来并不干净。
List<TestClass>
赞成
缺点
代码
public interface ILogEvent
{
string PreAllocatedProperty1 { get; set; }
string PreAllocatedProperty2 { get; set; }
string IndividualProperty1 { get; set; }
string IndividualProperty2 { get; set; }
}
与选项1类似,但是:
赞成
缺点:看起来好像很黑。
class LogEventPrototype
{
public string PreAllocatedProperty1 { get; set; }
public string PreAllocatedProperty2 { get; set; }
public string IndividualProperty1 { get; set; }
public string IndividualProperty2 { get; set; }
public LogEventPrototype() { GeneratePreAllocatedProperties(); }
private void GeneratePreAllocatedProperties()
{
// if you invoke the helper functions later again,
// they might return different results (e. g.: user identity, ...)
PreAllocatedProperty1 = Helper.ComplexFunction();
PreAllocatedProperty2 = Helper.AnotherComplexFunction();
}
}
class LogEvent : LogEventPrototype, ILogEvent
{
// just for creating the prototype, object will be in an INVALID state
private LogEvent() : base() { }
// object will be in a VALID state
public LogEvent(string individualProperty2)
: this()
{
if (individualProperty2 == null)
throw new ArgumentNullException();
IndividualProperty2 = individualProperty2;
}
public static LogEvent FromPrototype(LogEventPrototype prototype)
{
// clone manually
return new LogEvent(prototype.IndividualProperty2)
{
IndividualProperty1 = prototype.IndividualProperty1,
PreAllocatedProperty1 = prototype.PreAllocatedProperty1,
PreAllocatedProperty2 = prototype.PreAllocatedProperty2
};
}
}
不要将专用类用于原型,而是将LogEvent构造函数设置为public并冒无效的LogEvent对象。请改用Validate()方法,并希望客户端不要忘记使用它。