Skip to content

Instantly share code, notes, and snippets.

@sylvaindesve
Created January 6, 2020 16:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sylvaindesve/b26a2551d8b86d934ddf20d01912687c to your computer and use it in GitHub Desktop.
Save sylvaindesve/b26a2551d8b86d934ddf20d01912687c to your computer and use it in GitHub Desktop.
Domain Probe
// DOMAIN
// ------
interface ShoppingCartDomainProbe {
applyDiscountCode(): void;
discountCodeLookupFailed(error: string): void;
discountCodeLookupSucceeded(): void;
discountApplied(amountDiscounted: number): void;
}
interface DiscountService {
lookup(discountCode: string): number | undefined;
}
type ShoppingCartDomainProbeFactory = (discountCode: string) => ShoppingCartDomainProbe;
class ShoppingCart {
private _probeFactory: ShoppingCartDomainProbeFactory;
private _discountService: DiscountService;
constructor(discountService: DiscountService, probeFactory: ShoppingCartDomainProbeFactory) {
this._probeFactory = probeFactory;
this._discountService = discountService;
}
public applyDiscount(discountCode: string) {
const probe = this._probeFactory(discountCode);
probe.applyDiscountCode();
const amountDiscounted = this._discountService.lookup(discountCode);
if (amountDiscounted) {
probe.discountCodeLookupSucceeded();
probe.discountApplied(amountDiscounted);
} else {
probe.discountCodeLookupFailed(`no discount for code ${discountCode}`);
}
}
}
// INFRASTRUCTURE
// --------------
class DummyDiscountService implements DiscountService {
public lookup(discountCode: string): number | undefined {
if (discountCode === "HAPPY2020") {
return 10;
} else {
return undefined;
}
}
}
interface ObservationMetadata {
userId: string;
discountCode: string;
}
class ShoppingCartDomainProbeImpl implements ShoppingCartDomainProbe {
constructor(public metadata: ObservationMetadata) { }
public applyDiscountCode(): void {
console.log(`${(new Date()).toISOString()} ${this.metadata.userId} Applying discount code ${this.metadata.discountCode}`);
}
public discountCodeLookupFailed(error: string): void {
console.log(`${(new Date()).toISOString()} ${this.metadata.userId} Failed to lookup discount code ${this.metadata.discountCode}: ${error}`);
}
public discountCodeLookupSucceeded(): void {
console.log(`${(new Date()).toISOString()} ${this.metadata.userId} Found discount code ${this.metadata.discountCode}`);
}
public discountApplied(amountDiscounted: number): void {
console.log(`${(new Date()).toISOString()} ${this.metadata.userId} Discount code ${this.metadata.discountCode} grants ${amountDiscounted} discount`);
}
}
class ObservationContext {
constructor(public userId: string) {}
public createShoppingCartDomainProbe(discountCode: string): ShoppingCartDomainProbe {
return new ShoppingCartDomainProbeImpl({ userId: this.userId, discountCode });
}
}
// APPLICATION
// -----------
const run = (): void => {
const discountService = new DummyDiscountService();
const ctxt = new ObservationContext("sylvain");
const cart = new ShoppingCart(discountService, ctxt.createShoppingCartDomainProbe.bind(ctxt));
cart.applyDiscount("YEAH");
cart.applyDiscount("HAPPY2020");
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment