Skip to content

Instantly share code, notes, and snippets.

@smugen
Created December 3, 2022 12:21
Show Gist options
  • Save smugen/06c7d24a0ef0ddfd56f2db697e6c1801 to your computer and use it in GitHub Desktop.
Save smugen/06c7d24a0ef0ddfd56f2db697e6c1801 to your computer and use it in GitHub Desktop.
221203 Composite Design Pattern
abstract class Asset {
abstract getDetails(): string[];
}
class Machine implements Asset {
constructor(
private readonly machineId: number,
private readonly machineModel: string,
private readonly machineName: string,
) {}
getDetails(): string[] {
return [
`${this.constructor.name}#${this.machineId}(${this.machineModel}) "${this.machineName}"`,
];
}
}
enum DeviceType {
Water = 'Water',
Electricity = 'Electricity',
Oil = 'Oil',
Gas = 'Gas',
}
class Device implements Asset {
constructor(
private readonly deviceId: number,
private readonly deviceType: DeviceType,
private readonly deviceName: string,
) {}
getDetails(): string[] {
return [
`${this.constructor.name}#${this.deviceId}(${this.deviceType}) "${this.deviceName}"`,
];
}
}
class Station implements Asset {
constructor(
private readonly stationId: number,
private readonly stationNo: string,
private readonly stationName: string,
) {}
getDetails(): string[] {
return [
`${this.constructor.name}#${this.stationId}(${this.stationNo}) "${this.stationName}"`,
];
}
}
class Group implements Asset {
private readonly assets: Asset[] = [];
addAssets(...assets: Asset[]) {
this.assets.push(...assets);
}
// removeAsset
getDetails(): string[] {
return this.assets.map(asset => asset.getDetails()).flat();
}
}
if (require.main === module) {
main();
}
function main() {
let idSerial = 1;
const office = new Group();
const electricityMeter = new Device(
idSerial++,
DeviceType.Electricity,
'Building1 Electricity',
);
const waterMeter = new Device(
idSerial++,
DeviceType.Water,
'Building1 Water',
);
const department = new Station(idSerial++, 'GA01', 'General Affairs');
office.addAssets(electricityMeter, waterMeter, department);
const fab = new Group();
const linePCB = new Group();
const lineChassis = new Group();
const lineAssembly = new Group();
const fabElectricity = new Device(
idSerial++,
DeviceType.Electricity,
'Fab1 Electricity',
);
fab.addAssets(linePCB, lineChassis, lineAssembly, fabElectricity);
const smt = new Machine(idSerial++, 'SMT-01', 'Surface Mount Technology');
const cleaningFluid = new Device(
idSerial++,
DeviceType.Oil,
'Cleaning Fluid',
);
const smtChk = new Station(idSerial++, 'SC01', 'SMT Defect Check');
linePCB.addAssets(smt, cleaningFluid, smtChk);
const metalBender = new Machine(idSerial++, 'B-01', 'Metal Bender');
const metalWelder = new Machine(idSerial++, 'W-01', 'Metal Welder');
const metalDebrisBlower = new Device(
idSerial++,
DeviceType.Gas,
'Metal Debris Blower',
);
lineChassis.addAssets(metalBender, metalWelder, metalDebrisBlower);
const installing = new Station(
idSerial++,
'INS01',
'PCB installing into Chassis',
);
const packaging = new Station(idSerial++, 'PKG01', 'Product Packaging');
lineAssembly.addAssets(installing, packaging);
const plant = new Group();
plant.addAssets(office, fab);
console.log('plant', plant.getDetails());
/**
* plant [
* 'Device#1(Electricity) "Building1 Electricity"',
* 'Device#2(Water) "Building1 Water"',
* 'Station#3(GA01) "General Affairs"',
* 'Machine#5(SMT-01) "Surface Mount Technology"',
* 'Device#6(Oil) "Cleaning Fluid"',
* 'Station#7(SC01) "SMT Defect Check"',
* 'Machine#8(B-01) "Metal Bender"',
* 'Machine#9(W-01) "Metal Welder"',
* 'Device#10(Gas) "Metal Debris Blower"',
* 'Station#11(INS01) "PCB installing into Chassis"',
* 'Station#12(PKG01) "Product Packaging"',
* 'Device#4(Electricity) "Fab1 Electricity"'
* ]
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment