我有一个相同类型的对象集合,我们将其命名为DataItem
。用户可以在编辑器中查看和编辑这些项。还应该可以比较和合并不同的项,即DataItem
实例的某种类型的差异/合并。
DIFF功能应该比较项目的所有(相关)属性/字段,并检测可能的差异。然后,通过将选定的差异应用于其中一个项,合并功能应该能够合并两个实例。
例如(伪对象):
DataItem1 { DataItem2 {
Prop1 = 10 Prop1 = 10
Prop2 = 25 Prop2 = 13
Prop3 = 0 Prop3 = 5
Coll = { 7, 4, 8 } Coll = { 7, 4, 8, 12 }
} }
现在,应该向用户提供一个差异列表(即Prop2
、Prop3
和Coll
),他应该能够通过将一个项的值分配给另一个项来选择要消除的差异。他还应该能够选择是否要将DataItem1
的值分配给DataItem2
,反之亦然。
是否有应该用于实现此功能的通用实践?
由于同一个编辑器还应该提供撤销/重做功能(使用命令模式),所以我考虑重用ICommand
实现,因为这两种场景基本上都处理属性分配、集合更改等.我的想法是使用Difference
属性创建ICommand
对象,这些属性可以用于对这个特定的Difference
执行合并操作。
顺便说一句:编程语言是C#,带有.NET 3.5SP1/4.0。然而,我认为这更像是一个语言独立的问题。任何设计模式/想法/任何东西都欢迎!
发布于 2010-03-26 08:23:49
我就是这么做的。对于使用PropertyDiff类比较使用反射的属性值的对象,我有一个"Diff“类。把所有的代码都粘贴进去太麻烦了,但是这应该会给你一个想法。然后,不相等PropertyDiff对象的集合将显示给用户,用户可以选择保留或丢弃哪些对象。我们使用NHibernate,以便在内存中更改对象,然后将所有更改持久化到事务中。我们确实有一个较早的版本,它构建了一个SQL命令集合,并且也起作用,但您必须注意,这些命令的执行顺序和事务都是相同的。最糟糕的情况是,如果出现异常,并且这两个对象都是FUBAR。
PropertyDiff类表示两个对象上相同属性之间的比较。这只适用于简单的属性,并且有单独的代码来维护集合。
public class PropertyDiff
{
private bool _isEqual;
public PropertyDiff(string propertyName, object xvalue, object yvalue)
{
PropertyName = propertyName;
Xvalue = xvalue;
Yvalue = yvalue;
_isEqual = Xvalue == Yvalue;
}
public string PropertyName { get; private set; }
public object Xvalue { get; private set; }
public object Yvalue { get; private set; }
public bool IsEqual
{
get { return _isEqual; }
}
internal static IList<PropertyDiff> GetPropertyDiffs(IEnumerable<string> properties, object x, object y)
{
if (x.GetType() != y.GetType())
{
throw new ArgumentException("Objects must be of same type");
}
var list = new List<PropertyDiff>();
var t = x.GetType();
foreach (string propertyName in properties)
{
PropertyInfo pi = t.GetProperty(propertyName);
if (pi != null)
{
object xVal = pi.GetValue(x, null);
object yVal = pi.GetValue(y, null);
PropertyDiff propDiff = new PropertyDiff(propertyName, xVal, yVal);
list.Add(propDiff);
}
}
return list;
}
}
CompanyDiff类:
public class CompanyDiff
{
private List<string> _propertyNames;
private IList<PropertyDiff> _propertyDiffs;
public CompanyDiff(Company companyX, Company companyY)
{
this.CompanyX = companyX;
this.CompanyY = companyY;
// Build list of property names to be checked
_propertyNames = new List<string>()
{
"Type",
"Name",
"DBA"
// etc.
};
_propertyDiffs = PropertyDiff.GetPropertyDiffs(_propertyNames, this.CompanyX, this.CompanyY);
}
public Company CompanyX { get; private set; }
public Company CompanyY { get; private set; }
public IList<PropertyDiff> PropertyDiffs
{
get { return _propertyDiffs; }
}
}
https://stackoverflow.com/questions/2524663
复制相似问题