用简洁的语言表达......
目的:
创建一个可以在数据源中加载和保存对象列表的类。
当前方法:
我创建了一个接受两个委托作为构造参数的类:
private class Foo
{
public delegate List<object> LoadObjectsDelegate();
public delegate void SaveObjectsDelegate(List<object> data);
private LoadObjectsDelegate _loadDelegate;
private SaveObjectsDelegate _saveDelegate;
public Foo(LoadObjectsDelegate loadDelegate, SaveObjectsDelegate saveDelegate)
{
_loadDelegate = loadDelegate;
_saveDelegate = saveDelegate;
}
public List<object> Objects {get; private set;}
public void Load()
{
Objects = _loadDelegate.Invoke();
}
public void Save()
{
_saveDelegate.Invoke(Objects);
}
}
我想知道是否有更清洁的方法来做到这一点。
答案 0 :(得分:2)
从它的外观来看,我会说你正在尝试实现Repository模式,并具有一些扩展功能。我也认为没有必要尝试注入负载并保存逻辑,因为这是实现它们的存储库工作。如果加载和保存对象的逻辑对于域中的所有对象都是相同的,则将其在基类中实现,并在需要时在派生类中覆盖它。关于SO的This文章可以为您提供有关如何处理此模式的一些想法。
答案 1 :(得分:0)
好吧,有一件事我会把它变成通用的(Foo<T>
) - 你的调用者总是可以指定object
,如果他们真的需要,这意味着他们可以以更强类型的方式使用它必要的。
目前我不确定这个课程真的会增加很多价值,说实话。它实际上只是将这三个值组合在一起 - 而这就是全部。如果这就是你想要的那样,那很好......但对我来说感觉有点贫血。
答案 2 :(得分:0)
它不是更清洁,只是另一种方法。如果您在代理中指定的行为变化不大,请考虑Template Pattern。
private abstract class AbstractFoo
{
public List<object> Objects { get; private set; }
public List<object> Load();
public abstract void Save(List<object> data);
// add common functionality
}
private class ConcreteFoo : AbstractFoo
{
public override List<object> Load()
{
// do specific stuff
}
public override void Save(List<object> data)
{
// do specific stuff
}
}
缺点是每个特定行为都需要一个类。因此:如果委托给出的行为变化很大,或者您需要动态加载不同的行为,我发现您的委托方法是合适的。我通常发现模板模式更容易理解,更容易进行单元测试。
您可以更进一步:行为由模板模式中的继承指定。如果您选择具有接口的更抽象方法,则可以通过引用指定行为,而不是继承:
private interface IRepository
{
List<object> Load();
void Save(List<object> data);
}
private class FooBar
{
private IRepository repository;
public List<object> Objects { get; private set; }
public FooBar(IRepository repository)
{
this.repository = repository;
}
public void Load()
{
Objects = repository.Load();
}
public void Save()
{
repository.Save(Objects);
}
}
如果您需要某些特定行为,则需要实现从IRepository
派生的类。这种方法比模板模式更容易理解和单元测试。我经常最终用后一种方法替换模板模式。