是否可以使用此答案中提供的等效内容,但在Typescript中?
Subclassing a Java Builder class
以下是我到目前为止基类的内容:
export class ProfileBuilder {
name: string;
withName(value: string): ProfileBuilder {
this.name= value;
return this;
}
build(): Profile{
return new Profile(this);
}
}
export class Profile {
private name: string;
constructor(builder: ProfileBuilder) {
this.name = builder.Name;
}
}
扩展课程:
export class CustomerBuilder extends ProfileBuilder {
email: string;
withEmail(value: string): ProfileBuilder {
this.email = value;
return this;
}
build(): Customer {
return new Customer(this);
}
}
export class Customer extends Profile {
private email: string;
constructor(builder: CustomerBuilder) {
super(builder);
this.email= builder.email;
}
}
与其他线程一样,由于上下文的变化,我无法按此顺序构建客户:
let customer: Customer = new CustomerBuilder().withName('John')
.withEmail('john@email.com')
.build();
我目前正在尝试使用泛型来解决这个问题,但是在为我的setter方法返回this指针时遇到了麻烦(类型不能分配给类型T)。有什么想法吗?
答案 0 :(得分:2)
我最近遇到了同样的要求,这是我的解决方案,如果我们创建一个配置文件构建器类,我们可以从我们的客户构建器扩展它,并使用super调用基础构建器。
class ProfileBuilder {
private name: string;
constructor() {
this.name = undefined;
}
public withName(name: string) {
this.name = name;
return this;
}
public build() {
return {
name: this.name
}
}
}
class CustomerBuilder extends ProfileBuilder {
private email: string;
constructor() {
super();
this.email = undefined;
}
public withEmail(email: string) {
this.email = email;
return this;
}
public build() {
const base = super.build();
return {
...base,
email: this.email
}
}
}
现在,您可以根据自己的要求创建客户:
const customer = new CustomerBuilder()
.withName("John")
.withEmail("john@email.com")
.build();
答案 1 :(得分:0)
找到解决方案!在我提到的另一个线程上查看不同的答案后,我最终创建了一个基本抽象类和构建器,然后为每个类/构建器对进行扩展:
abstract class BaseProfileBuilder<T extends BaseProfile, B extends BaseProfileBuilder<T, B>> {
protected object: T;
protected thisPointer: B;
protected abstract createObject(): T;
protected abstract getThisPointer(): B;
constructor() {
this.object = this.createObject();
this.thisPointer = this.getThisPointer();
}
withName(value: string): B {
this.object.name = value;
return this.thisPointer;
}
build(): T {
return this.object;
}
}
abstract class BaseProfile {
name: string;
}
class ProfileBuilder extends BaseProfileBuilder<Profile, ProfileBuilder> {
createObject(): Profile {
return new Profile();
}
getThisPointer(): ProfileBuilder {
return this;
}
}
class Profile extends BaseProfile {
}
class CustomerBuilder extends BaseProfileBuilder<Customer, CustomerBuilder> {
createObject(): Customer {
return new Customer();
}
getThisPointer(): CustomerBuilder {
return this;
}
withEmail(value: string): CustomerBuilder {
this.object.email = value;
return this;
}
}
class Customer extends BaseProfile {
email: string;
}
let customer: Customer = new CustomerBuilder().withName('John')
.withEmail('john@email.com')
.build();
console.log(customer);