0% found this document useful (0 votes)
32 views3 pages

5.1 Solid - Isp.js

The document defines an aggregation function that allows mixins of classes to extend a base class. It defines various printer classes like MultiFunctionPrinter and OldFashionedPrinter that extend an abstract Machine class. It also defines a Printer and Scanner class to be mixed into a Photocopier class using the aggregation function.

Uploaded by

Pivo Sok
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views3 pages

5.1 Solid - Isp.js

The document defines an aggregation function that allows mixins of classes to extend a base class. It defines various printer classes like MultiFunctionPrinter and OldFashionedPrinter that extend an abstract Machine class. It also defines a Printer and Scanner class to be mixed into a Photocopier class using the aggregation function.

Uploaded by

Pivo Sok
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 3

var aggregation = (baseClass, ...

mixins) => {
class base extends baseClass {
constructor (...args) {
super(...args);
mixins.forEach((mixin) => {
copyProps(this,(new mixin));
});
}
}
let copyProps = (target, source) => { // this function copies all properties and
symbols, filtering out some special ones
Object.getOwnPropertyNames(source)
.concat(Object.getOwnPropertySymbols(source))
.forEach((prop) => {
if (!prop.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|
apply|toString|length)$/))
Object.defineProperty(target, prop,
Object.getOwnPropertyDescriptor(source, prop));
})
};
mixins.forEach((mixin) => {
// outside constructor() to allow aggregation(A,B,C).staticFunction() to be
called etc.
copyProps(base.prototype, mixin.prototype);
copyProps(base, mixin);
});
return base;
};

class Document
{

class Machine
{
constructor()
{
if (this.constructor.name === 'Machine')
throw new Error('Machine is abstract!');
}

print(doc) {}
fax(doc) {}
scan(doc) {}
}

class MultiFunctionPrinter extends Machine


{
print(doc) {
//
}

fax(doc) {
//
}

scan(doc) {
//
}
}

class NotImplementedError extends Error


{
constructor(name)
{
let msg = `${name} is not implemented!`;
super(msg);
// maintain proper stack trace
if (Error.captureStackTrace)
Error.captureStackTrace(this, NotImplementedError);
// your custom stuff here :)
}
}

class OldFashionedPrinter extends Machine


{
print(doc) {
// ok
}

// omitting this is the same as no-op impl

// fax(doc) {
// // do nothing
// }

scan(doc) {
// throw new Error('not implemented!');
throw new NotImplementedError(
'OldFashionedPrinter.scan')
}
}

// solution
class Printer
{
constructor()
{
if (this.constructor.name === 'Printer')
throw new Error('Printer is abstract!');
}

print(){}
}

class Scanner
{
constructor()
{
if (this.constructor.name === 'Scanner')
throw new Error('Scanner is abstract!');
}

scan(){}
}

class Photocopier extends aggregation(Printer, Scanner)


{
print()
{
// IDE won't help you here
}

scan()
{
//
}
}

// we don't allow this!


// let m = new Machine();

let printer = new OldFashionedPrinter();


printer.fax(); // nothing happens
//printer.scan();

You might also like