2

我是一个团队的一员,负责将我们旧的 VB6 UI/COBOL 数据库应用程序改造成现代。在我被录用之前,我决定(主要是关于销售,我敢肯定)在数据库之前重做 UI。所以,现在我们使用 WPF 和 MVVM 取得了很好的效果,到目前为止效果非常好,尤其是使用 CSLA 作为我们的模型层。

但是,由于我们的开发与旧产品的下一个版本并行,我们受到了一些限制。我们无法对对 COBOL 数据库的调用进行任何更改(或最小更改)。到目前为止,这一切都很好,尽管如果您相信的话,可以追溯到 SQL Server 的辉煌岁月。

关于我们的 BO 设计,我遇到了一个特别令人讨厌的障碍,那就是处理列表中返回的“轻量级”业务对象及其“完整”对应项。让我尝试构建一个示例:

假设我们在数据库中有一个带有一堆字段的人员对象。当我们对该表进行搜索时,我们不会返回所有字段,因此我们用这些填充我们的 lite 对象。这些字段可能是也可能不是完整人员的子集。我们可能已经进行了一两次连接以检索特定于搜索的其他一些信息。但是,如果我们想编辑我们的 person 对象,我们必须再次调用以获取完整版本来填充 UI。这给我们留下了两个对象,并试图在 1 个 VM 中处理它们的状态,同时试图在删除、编辑和添加之后保持人员列表在它所在的任何父对象上保持同步。最初,我让我们的 lite person 对象派生自 ReadOnlyBase<>。但是现在我正在处理与完整 BO 列表相同的列表行为,除了半满,半精简,

有没有其他人遇到过并找到解决方案?睡在上面之后,我想出了这个潜在的解决方案。如果我们将完整版和精简版的 BO 包装在另一个 BO 中会怎样,如下所示:

public class PersonFull : BusinessBase<PersonFull>
{
  ...
}
public class PersonLite : BusinessBase<PersonLite>
{
  ...
}

public class Person : BusinessBase<Person>
{
  public PersonFull PersonFull;
  public PersonLite PersonLite;
}
public class PersonList : BusinessListBase<PersonList, Person>
{
}

显然,一切都是 CSLA 注册的属性等,但为了简洁起见,它们是那里的字段。在这种情况下, Person 和 PersonList 将包含所有工厂方法。在搜索操作之后,PersonList 将由 PersonLite 成员全部填充且 PersonFull 对象全部为空的 Person 对象填充。如果我们需要获得完整版本,我们只需告诉 Person 对象这样做,现在我们有了 PersonFull 对象,因此我们可以填充编辑 UI。如果要删除 Person 对象,我们可以使用适当的 CSLA 删​​除程序轻松地执行此操作,同时仍然在所有正在侦听它的 VM 中保持列表的完整性。

所以,我希望这对每个人都有意义,如果有人有不同的解决方案,他们一定会成功采用或批评这个解决方案!

谢谢!

(转自: http ://forums.lhotka.net/forums/thread/35576.aspx )

4

2 回答 2

3
public class PersonLite : ReadOnlyBase<PersonLite>
{
    public void Update(PersonFull person) { }
}

public class PersonFull : BusinessBase<PersonFull>
{
    // blah blah
}

我会用对“完整”对象所做的更改来更新“精简”对象,并将其保留为ReadOnlyBase. 重要的是要记住,“ReadOnly”中的“只读”是ReadOnlyBase指仅从数据库中读取而从未保存到其中的对象。一个不太优雅但更准确的名称是NotSavableBase,因为这样的对象DataPortal_XYZ除了获取之外没有任何机制。出于显而易见的原因,此类对象通常具有不可变的属性,但它们并非必须如此。ReadOnlyBase派生自Core.BindableBase和实现INotifyPropertyChanged,因此更改其属性的值可以很好地用于绑定。

当您保存“完整”对象时,将新保存的实例传递给Update(PersonFull)位于列表中的实例的方法,并从“完整”对象更新“精简”对象的属性。

我已经多次使用这种技术并且效果很好。

于 2009-08-16T08:27:10.227 回答
-1

如果您查看 Rocky 随 CSLA 框架提供的示例,您会注意到他总是将只读对象与读/写对象分开。我认为这样做是有充分理由的,因为行为将完全不同。只读对象将更多地基于性能,它们的验证将非常不同,并且通常具有更少的信息。读/写对象不会基于性能,并且严重依赖验证、授权等。

然而,这让你陷入了目前所处的困境。我要做的是重载每个类的构造函数,这样你就可以在彼此之间传递它们,并从彼此“复制”你需要的东西。

像这样的东西:

public class PersonLite : BusinessBase<PersonLite>
{
    public PersonLite(PersonFull fullPerson)
    {
        //copy from fullPerson's properties or whatever
    }
}

public class PersonFull : BusinessBase<PersonFull>
{
    public PersonFull(PersonLite litePerson)
    {
        //copy from litePerson's properties or whatever
    }
}

你也可以使用工厂模式来做到这一点,我相信这是 Rocky 的偏好。

于 2009-08-14T16:18:23.263 回答