Decorator Design Pattern
Video Lecture
Overview
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.
Terminology
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.
Decorator UML Diagram

Source Code
./src/decorator/decorator-concept.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | // Decorator Concept Sample Code
interface IComponent {
method(): string
}
class Component implements IComponent {
method(): string {
return 'Component Method'
}
}
class Decorator implements IComponent {
#object: IComponent
constructor(object: IComponent) {
this.#object = object
}
method(): string {
return `Decorator Method(${this.#object.method()})`
}
}
// The Client
const COMPONENT = new Component()
console.log(COMPONENT.method())
// The component can be decorated
const Decorated = new Decorator(COMPONENT)
console.log(Decorated.method())
// The decorated component can be decorated again
const Decorated2 = new Decorator(Decorated)
console.log(Decorated2.method())
|
Output
node ./dist/decorator/decorator-concept.js
Component Method
Decorator Method(Component Method)
Decorator Method(Decorator Method(Component Method))
Decorator Use Case
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.
Example UML Diagram

Source Code
./src/decorator/client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | // Decorator Use Case Example Code
import Value from './value'
import Add from './add'
import Sub from './sub'
const A = Value(1)
const B = Value(2)
const C = Value(5)
console.log(Add(A, B).value)
console.log(Add(A, 100).value)
console.log(Sub(C, A).value)
console.log(Sub(Add(C, B), A).value)
console.log(Sub(100, 101).value)
console.log(Add(Sub(Add(C, B), A), 100).value)
console.log(Sub(123, Add(C, C)).value)
console.log(Add(Sub(Add(C, 10), A), 100).value)
console.log(A.value)
console.log(B.value)
console.log(C.value)
|
./src/decorator/value.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | export interface IValue {
value: number
}
class _Value implements IValue {
value: number
constructor(value: number) {
this.value = value
}
}
export default function Value(value: number): IValue {
return new _Value(value)
}
|
./src/decorator/add.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import { IValue } from './value'
class _Add implements IValue {
value: number
constructor(val1: IValue | number, val2: IValue | number) {
const left = Object.prototype.hasOwnProperty.call(val1, 'value')
? (val1 as IValue).value
: (val1 as number)
const right = Object.prototype.hasOwnProperty.call(val2, 'value')
? (val2 as IValue).value
: (val2 as number)
this.value = left + right
}
}
export default function Add(
val1: IValue | number,
val2: IValue | number
): IValue {
return new _Add(val1, val2)
}
|
./src/decorator/sub.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import { IValue } from './value'
class _Sub implements IValue {
value: number
constructor(val1: IValue | number, val2: IValue | number) {
const left = Object.prototype.hasOwnProperty.call(val1, 'value')
? (val1 as IValue).value
: (val1 as number)
const right = Object.prototype.hasOwnProperty.call(val2, 'value')
? (val2 as IValue).value
: (val2 as number)
this.value = left - right
}
}
export default function Sub(
val1: IValue | number,
val2: IValue | number
): IValue {
return new _Sub(val1, val2)
}
|
Output
node ./dist/decorator/client.js
3
101
4
6
-1
106
113
114
1
2
5
Summary
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.