DEV Community

Discussion on: How to keep list of different payment methods in a web account following DDD principles?

Collapse
 
benjioe profile image
Benjioe • Edited

You can encapsulate payment in his own ValueObject :


export class Account {
  private AccountPaymentMethod paymentMethod;

  addPaymentMethod(paymentMethod: IPaymentMethod): void {
    this.paymentMethod= this.paymentMethod.addMethod(paymentMethod);
  }

}

class AccountPaymentMethod {
  constructor(private _paymentMethods: IPaymentMethod[], private _defaultPaymentMethod: IPaymentMethod) {}

  default(): IPaymentMethod {
    return this._defaultPaymentMethod;
  }

  changeDefault(paymentMethod: IPaymentMethod): AccountPaymentMethod {
    return new AccountPaymentMethod(this._paymentMethods, paymentMethod);
  }

  removeMethod(paymentMethod: IPaymentMethod): AccountPaymentMethod {
    throw new Error("Method not implemented.");
  }

  addMethod(paymentMethod: IPaymentMethod): AccountPaymentMethod {
    paymentMethod.init(this);
    return new AccountPaymentMethod(
       [...this._paymentMethods, paymentMethod], 
       _defaultPaymentMethod: IPaymentMethod
    );
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
atmosphere profile image
Atmosphere

It looks really interesting and I like your approach to encapsulate logic with payment methods in one object. Thanks!

Collapse
 
benjioe profile image
Benjioe • Edited

And I thinks your method create is too generic, you can be more explicit :


type PaymentMethodParam = {
  paymentMethods: IPaymentMethod[]
  defaultPaymentMethod: IPaymentMethod
}

export class Account {
  static create(user: User, {paymentMethods, defaultPaymentMethod} : PaymentMethodParam): Result<Account> {
     // ...
  }
  static createAccountForFutur(user: User,  createdAt: Date /* Date encapsulate Moment for the day Moment will be abandonned */): Result<Account> {
     // for some reason, you wants to create an Account with createdAt !== today
    //  and you don't want to let them pay
  }
}
Enter fullscreen mode Exit fullscreen mode