如何设计 class Bill 和 class SimplifiedBill 之间的关系?

How to design relation between a class Bill and a class SimplifiedBill?

所以正如标题提到的,我有 SimplifiedBill,它只有 datefinalPayment,我还有Bill,它与 SimplifiedBill 具有相同的属性,但也包含所有其他详细信息(税收用户数据服务,等等)。

Bill 的解决方案可能是从 SimplifiedBill 继承,但我不认为这在概念上是正确的,因为 SimplifiedBill 是你从 [=13] 中得到的东西=],所以 Bill 不是 "below" SimplifiedBill,它没有继承任何东西。

关于如何在此处实施 class 设计的任何想法?

编辑: 过程如下。
我有一个从后面获得的 SimplifiedBill 列表,当我单击其中一个时,我请求并从 api 中获得 Bill 并进入详细视图。

如果您想知道,我正在使用 Angular,并且我有一个 ListComponent(或视图),其中我有我的 SimpleBill objects ,当我点击其中一个时,我会转到 DetailComponent,在那里我可以看到特定的 Bill。当我从一个视图转到另一个视图时,我无法传输 object SimpleBill,只能传输其 ID(或其他字段)。

不,我同意,从 SimplifiedBill 继承在概念上是不正确的。 一般来说,我认为谨慎使用继承是明智的。我很少看到它被正确使用。

相反,我会推荐一种组合方法:如果 Bill 包含 SimplifiedBill,那么我认为拥有一个具有详细信息属性的数据结构 Bill 是有意义的:

let bill = {
  details: {...},
  simplifiedBill: {...}
}

请注意,我在这里使用了一个简单的对象(当您使用 javascript 时,它可能也值得考虑),但它同样适用于基于 class 的方法。 不过,您可能想为简化的账单想一个不同的名称。也许像 "summary".

但总的来说,您想到这里可能不太适合的继承概念是件好事。

我倾向于认为你可能甚至不需要这里的关系;听起来 SimplifiedBill class 更像是 Bill class.

的简单投影

解决这个问题的一种方法是将两个 class 完全分开,并引入第三个 class,类似于 SimplifiedBillFactory,需要 [=12] =] 并生成 SimplifiedBill.

例如(伪代码,可能不是有效的打字稿!)

export class SimplifiedBillFactory
{

  createSimplifiedBill(bill: Bill) : SimplifiedBill
  {
     return new SimplifiedBill{
             billId=bill.Id,
             date=bill.date,
             finalPayment=bill.calculateFinalPayment()
     };         
   }
}

这种方法的一个优点是,如果您需要扩充 SimplifiedBill 以包含更多详细信息(例如可能有一些聚合,例如订单项的总数等),可以在此处轻松完成 class。此外,它鼓励您将法案的实际行为保留在 Bill class 本身中,并通过方法公开它们(例如 Bill 上的 calculateFinalPayment 方法)

您也可以只在 Bill class 上使用工厂方法而不是单独的工厂 class,但我个人更愿意将其分开,例如,如果除了 Bill class 之外,您稍后还需要使用其他 class 来创建您的 SimplifiedBill 实例。

有趣的问题,

继承是一种is-a关系。当你在它们之间建立继承关系时,问问自己A是不是B。

  • 第一个问题:什么是最简单的法案或法案至少应该有什么?答案也回答了 Bill 应该是什么。

由于SimpleBill也是Bill的一种,所以SimpleBill的子集使得Bill,Bill本身可以简单到只有一个billId(根据评论)。所以 Bill 将是:

interface Bill{
    billId: string;
}
  • 第二题:VerboseBillSimpleBill还是相反?,答案也回答了它们之间是否存在继承关系

奇怪的是SimpleBillVerboseBill或者相反,所以他们没有继承关系;

以后你可能还有其他的账单,比如AaaBill{taxes}BbbBill{services}...,他们有继承关系吗?但他们都是 Bill!

我的建议:

export interface SimpleBill extends Bill{
  date: number;
  finalPayment: number;

}

export interface VerboseBill extends Bill{
    date: number;
    finalPayment: number;
    taxes:number;
    services;...
    userData;...
}

export namespace Bill{

    export function simplify(bill:Bill): SimpleBill{
        return {id: bill.id, date: bill.date, finalPayment: bill.finalPayment};
    }

    export function verbose(bill:Bill): VerboseBill{
        if((bill as VerboseBill).taxes !==undefined){
            return bill as VerboseBill;
        }
        return fetchVerboseBill(bill.id);
    }
}

export namespace SimpleBill{
    export const verbose = Bill.verbose
}

export namespace VerboseBill{
    export const simplify = Bill.simplify
}