目前,我对用例概念的理解不够好--太多抽象的定义,但没有特定的例子。第20章业务规则的用例部分不包括任何代码,至少不包括UML示例。
目前的问题是围绕以下段落进行讨论:
用例是一个对象。它有一个或多个实现特定于应用程序的业务规则的功能。它还具有数据元素,其中包括输入数据、输出数据和与其交互的适当实体的引用。“清洁建筑”
这提出了很多问题,但按照这样的规则,我必须把话题集中在一个问题上。我将从:“用例必须扩展实体”开始?

实体是纯粹的商业,仅此而已。
这些规则不会在手动环境中使用,因为只有作为自动化系统的一部分才有意义。
的示例系统
限制
严格地说,无论这些规则是否在电脑上实施,这些规则都会使企业赚钱或省钱。即使他们被手工处决,他们也会赚钱或省钱。
以下TypeScript类完全服从上述概念,因为它只包含没有计算机化的存在的数据。
class Product {
public title: string;
public price__dollars__withoutTax: number; // The "__XX" is the Clarification postfix
public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
this.title = properties.title;
this.price__dollars__withoutTax = properties.price__dollars__withoutTax;
}
}假设我问客户“标题中的最小和最大字符数是多少”?客户回答说:“我没有想过这个问题。在您正在开发的系统中,请您自己决定,同时不要有任何不便。”
我已经核对了统计数字,并且知道大多数标题都小于200个字符。如果有一定的差额,就让它达到300。
class Product {
public title: string;
public price__dollars__withoutTax: number;
public readonly TITLE_MINIMAL_CHARACTERS_COUNT: number = 2;
public readonly TITLE_MAXIMAL_CHARACTERS_COUNT: number = 300;
public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
this.title = properties.title;
this.price__dollars__withoutTax = properties.price__dollars__withoutTax;
}
}我用适当的类字段表达了上述限制,但是如果没有计算机化,这些限制就不存在--企业(关键)业务规则的概念被违反了。要解决这些问题,我必须将这些限制移到用例类:
class Product {
public title: string;
public price__dollars__withoutTax: number;
public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
this.title = properties.title;
this.price__dollars__withoutTax = properties.price__dollars__withoutTax;
}
}
class ProductUseCase extends Product {
public readonly TITLE_MINIMAL_CHARACTERS_COUNT: number = 2;
public readonly TITLE_MAXIMAL_CHARACTERS_COUNT: number = 300;
public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
super(properties);
}
}所需的新字段
由于某些原因,在各种应用程序中,实体经常需要标识符。但是,ID仅适用于应用程序,因此必须出现在用例中:
class Product {
public title: string;
public price__dollars__withoutTax: number; // The "__XX" is the Clarification postfix
public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
this.title = properties.title;
this.price__dollars__withoutTax = properties.price__dollars__withoutTax;
}
}
class ProductUseCase extends Product {
public readonly ID: number = ProductUseCase.generateID();
private static counterForID_Generating: number = 0;
public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
super(properties);
}
private static generateID(): number {
ProductUseCase.counterForID_Generating++;
return ProductUseCase.counterForID_Generating;
}
}这样,在大多数情况下,关键业务规则中的每个实体都必须由用例包装。
图20.2中示例的

因此,“用例是一个对象”。很难用一个函数来实现上面的用例--它将是具有一个公共和多个私有方法的类。
对于这个例子,不需要从LoanUseCase扩展Loan。守则草案如下:
class Loan {
public principle: Loan.Principles;
public rate__percentage: number;
public period__months: number;
public constructor(constructorParameters: Loan.ContructorParameters) {
this.principle = constructorParameters.principle;
this.rate__percentage = constructorParameters.rate__percentage;
this.period__months = constructorParameters.period__months;
}
public makePayment(amount__dollars: number): void {
}
public applyInterest(): void { /* ... */ }
public chargeLetFee(): void { /* ... */ }
}
namespace Loan {
export type ContructorParameters = Readonly<{
principle: Loan.Principles;
rate__percentage: number;
period__months: number;
}>;
export enum Principles {
standard = "STANDARD",
forYoungFamilies = "FOR_YONG_FAMILIES"
}
}
type CustomerRawData = {
firstName: string;
lastName: string;
// ...
};
class LoanUseCase {
public static issueLoanOfPrimaryCourseIfPossible(customerRawData: CustomerRawData): Loan | null {
if (!LoanUseCase.isCustomerDataValid(customerRawData)) {
return null;
}
if (!LoanUseCase.isCreditScoreEnough(customerRawData)) {
return null;
}
// create new customer and save him to data store
return new Loan({
period__months: 12,
principle: Loan.Principles.standard,
rate__percentage: 15
});
}
private static isCustomerDataValid(customerRawData: CustomerRawData): boolean {
// validate name ...
// validate address, birthdate, etc.
return true;
}
private static isCreditScoreEnough(customerRawData: CustomerRawData): boolean {
// ...
return true;
}
}发布于 2022-09-25 10:03:44
“用例必须扩展实体”?
简单地说,答案是否定的,用例不应该扩展实体。extends关键字表示继承,这意味着从面向对象的角度来看类之间的"IS-A“关系。
继承通过在创建对象时将子类和超类中的所有数据和行为合并到同一个实例中,从而定义子类与超类的紧密耦合。
使用用例类扩展实体类将导致在同一个对象中与用例一起定义关键业务数据,这意味着两者之间没有分离。
强调同一段中的另一行:
用例是一个对象。它有一个或多个实现特定于应用程序的业务规则的功能。它还具有数据元素,其中包括输入数据、输出数据和与其交互的适当实体的引用。
继承违背了清洁体系结构中的指导方针,该指南建议的关系要比继承松散得多,用例包含对与其交互的任何实体的引用,而不是实体函数和数据成为用例对象的一部分。
https://softwareengineering.stackexchange.com/questions/441243
复制相似问题