├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── src ├── behavioral │ ├── chain_of_responsibility │ │ ├── AuthenticationHandler.ts │ │ ├── AuthorizationHandler.ts │ │ ├── Client.ts │ │ ├── Handler.ts │ │ └── LogHandler.ts │ ├── command │ │ ├── Client.ts │ │ ├── Command.ts │ │ ├── Invoker.ts │ │ ├── RestartCommand.ts │ │ ├── Server.ts │ │ ├── StartCommand.ts │ │ └── StopCommand.ts │ ├── interpreter │ │ ├── AbstractExpression.ts │ │ ├── Client.ts │ │ ├── Context.ts │ │ ├── MinusExpression.ts │ │ ├── MultiplyExpression.ts │ │ ├── NumberExpression.ts │ │ ├── Parser.ts │ │ └── PlusExpression.ts │ ├── iterator │ │ ├── Client.ts │ │ ├── Iterator.ts │ │ └── NumberIterator.ts │ ├── mediator │ │ ├── Client.ts │ │ ├── Mediator.ts │ │ └── User.ts │ ├── memento │ │ ├── Client.ts │ │ ├── Memento.ts │ │ └── Originator.ts │ ├── observer │ │ ├── Button.ts │ │ ├── Client.ts │ │ ├── Expression.ts │ │ ├── InputText.ts │ │ └── Observer.ts │ ├── state │ │ ├── Client.ts │ │ ├── LowerCaseState.ts │ │ ├── State.ts │ │ ├── StateContext.ts │ │ └── UpperCaseState.ts │ ├── strategy │ │ ├── Client.ts │ │ ├── Context.ts │ │ ├── Entity.ts │ │ ├── Repository.ts │ │ ├── RepositoryDatabase.ts │ │ └── RepositoryMemory.ts │ ├── template_method │ │ ├── Client.ts │ │ ├── Item.ts │ │ ├── LocalOrder.ts │ │ ├── OnlineOrder.ts │ │ └── Order.ts │ └── visitor │ │ ├── Client.ts │ │ ├── HolidayTaxVisitor.ts │ │ ├── Liquor.ts │ │ ├── Product.ts │ │ ├── TaxVisitor.ts │ │ ├── Tobacco.ts │ │ ├── Visitable.ts │ │ └── Visitor.ts ├── creational │ ├── abstract_factory │ │ ├── AbstractFactory.ts │ │ ├── Client.ts │ │ ├── GetOrder.ts │ │ ├── Order.ts │ │ ├── OrderRepository.ts │ │ ├── OrderRepositoryDatabase.ts │ │ ├── OrderRepositoryMemory.ts │ │ ├── ProductRepository.ts │ │ ├── ProductRepositoryDatabase.ts │ │ ├── ProductRepositoryMemory.ts │ │ ├── RepositoryDatabaseFactory.ts │ │ └── RepositoryMemoryFactory.ts │ ├── builder │ │ ├── Client.ts │ │ ├── User.ts │ │ └── UserBuilder.ts │ ├── factory_method │ │ ├── Client.ts │ │ ├── MagicMazeGame.ts │ │ ├── MagicRoom.ts │ │ ├── MazeGame.ts │ │ ├── OrdinaryMazeGame.ts │ │ ├── OrdinaryRoom.ts │ │ └── Room.ts │ ├── prototype │ │ ├── Client.ts │ │ ├── Product.ts │ │ └── Prototype.ts │ └── singleton │ │ ├── Client.ts │ │ └── Singleton.ts └── structural │ ├── adapter │ ├── Client.ts │ ├── PagSeguroTransaction.ts │ ├── PagSeguroTransactionAdapter.ts │ ├── PayPalTransaction.ts │ ├── PayPalTransactionAdapter.ts │ └── Transaction.ts │ ├── bridge │ ├── Abstraction.ts │ ├── Client.ts │ ├── ConcreteAbstractionA.ts │ ├── ConcreteImplementorA.ts │ ├── ConcreteImplementorB.ts │ └── Implementor.ts │ ├── composite │ ├── Client.ts │ ├── Component.ts │ ├── Composite.ts │ └── Leaf.ts │ ├── decorator │ ├── Client.ts │ ├── Component.ts │ ├── ConcreteComponent.ts │ ├── ConcreteDecorator.ts │ └── Decorator.ts │ ├── facade │ ├── Client.ts │ ├── Facade.ts │ ├── ImplementationA.ts │ ├── ImplementationB.ts │ └── ImplementationC.ts │ ├── flyweight │ ├── Client.ts │ ├── ConcreteFlyweight.ts │ ├── Flyweight.ts │ ├── FlyweightFactory.ts │ └── UnsharedConcreteFlyweight.ts │ └── proxy │ ├── Client.ts │ ├── Proxy.ts │ ├── RealSubject.ts │ └── Subject.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Este conteúdo é parte do curso Clean Code e Clean Architecture da Branas.io 2 | 3 | Para mais informações acesse: 4 | 5 | https://app.branas.io/clean-code-e-clean-architecture 6 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "design_patterns", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "1.0.0", 9 | "license": "ISC", 10 | "dependencies": { 11 | "typescript": "^4.3.2" 12 | } 13 | }, 14 | "node_modules/typescript": { 15 | "version": "4.3.2", 16 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", 17 | "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", 18 | "bin": { 19 | "tsc": "bin/tsc", 20 | "tsserver": "bin/tsserver" 21 | }, 22 | "engines": { 23 | "node": ">=4.2.0" 24 | } 25 | } 26 | }, 27 | "dependencies": { 28 | "typescript": { 29 | "version": "4.3.2", 30 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", 31 | "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "design_patterns", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "tsc": "tsc" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "typescript": "^4.3.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/chain_of_responsibility/AuthenticationHandler.ts: -------------------------------------------------------------------------------- 1 | import Handler from "./Handler"; 2 | 3 | export default class AuthenticationHandler extends Handler { 4 | constructor() { 5 | super(); 6 | } 7 | public handlerRequest(req: string) { 8 | console.log("Authentication:", req); 9 | if (req === "Request 2") return false; 10 | return true; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/chain_of_responsibility/AuthorizationHandler.ts: -------------------------------------------------------------------------------- 1 | import Handler from "./Handler"; 2 | 3 | export default class AuthorizationHandler extends Handler { 4 | constructor() { 5 | super(); 6 | } 7 | public handlerRequest(req: string) { 8 | console.log("Authorization:", req); 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/behavioral/chain_of_responsibility/Client.ts: -------------------------------------------------------------------------------- 1 | import LogHandler from "./LogHandler"; 2 | import AuthenticationHandler from "./AuthenticationHandler"; 3 | import AuthorizationHandler from "./AuthorizationHandler"; 4 | 5 | const reqs = ["Request 1", "Request 2", "Request 3"]; 6 | 7 | const logHandler = new LogHandler(); 8 | const authenticationHandler = new AuthenticationHandler(); 9 | const authorizationHandler = new AuthorizationHandler(); 10 | 11 | logHandler.setHandler(authenticationHandler); 12 | authenticationHandler.setHandler(authorizationHandler); 13 | 14 | for (const req of reqs) { 15 | logHandler.operation(req); 16 | } 17 | -------------------------------------------------------------------------------- /src/behavioral/chain_of_responsibility/Handler.ts: -------------------------------------------------------------------------------- 1 | export default abstract class Handler { 2 | private handler?: Handler; 3 | 4 | constructor() { 5 | } 6 | 7 | public setHandler(handler: Handler): void { 8 | this.handler = handler; 9 | } 10 | 11 | public operation(req: string): void { 12 | if (this.handlerRequest(req)) { 13 | this.handler?.operation(req); 14 | } 15 | } 16 | 17 | abstract handlerRequest(msg: string): boolean; 18 | } 19 | -------------------------------------------------------------------------------- /src/behavioral/chain_of_responsibility/LogHandler.ts: -------------------------------------------------------------------------------- 1 | import Handler from "./Handler"; 2 | 3 | export default class LogHandler extends Handler { 4 | constructor() { 5 | super(); 6 | } 7 | public handlerRequest(req: string) { 8 | console.log("Log:", req); 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/behavioral/command/Client.ts: -------------------------------------------------------------------------------- 1 | import StartCommand from "./StartCommand"; 2 | import StopCommand from "./StopCommand"; 3 | import RestartCommand from "./RestartCommand"; 4 | import Invoker from "./Invoker"; 5 | import Server from "./Server"; 6 | 7 | const server = new Server(); 8 | const start = new StartCommand(server); 9 | const stop = new StopCommand(server); 10 | const restart = new RestartCommand(server); 11 | const invoker = new Invoker(); 12 | 13 | invoker.storeAndExecute(start); 14 | invoker.storeAndExecute(restart); 15 | invoker.storeAndExecute(stop); 16 | console.log(invoker.commands); -------------------------------------------------------------------------------- /src/behavioral/command/Command.ts: -------------------------------------------------------------------------------- 1 | export default abstract class Command { 2 | abstract execute(): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/behavioral/command/Invoker.ts: -------------------------------------------------------------------------------- 1 | import Command from "./Command"; 2 | 3 | export default class Invoker { 4 | commands: Command[]; 5 | 6 | constructor() { 7 | this.commands = []; 8 | } 9 | 10 | public storeAndExecute(cmd: Command) { 11 | this.commands.push(cmd); 12 | cmd.execute(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/command/RestartCommand.ts: -------------------------------------------------------------------------------- 1 | import Command from "./Command"; 2 | import Server from "./Server"; 3 | 4 | export default class RestartCommand extends Command { 5 | private server: Server; 6 | 7 | constructor(server: Server) { 8 | super(); 9 | this.server = server; 10 | } 11 | 12 | public execute(): void { 13 | this.server.restart(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/command/Server.ts: -------------------------------------------------------------------------------- 1 | export default class Server { 2 | start () { 3 | console.log("Start server"); 4 | } 5 | 6 | stop () { 7 | console.log("Stop server"); 8 | } 9 | 10 | restart () { 11 | console.log("Restart server"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/command/StartCommand.ts: -------------------------------------------------------------------------------- 1 | import Command from "./Command"; 2 | import Server from "./Server"; 3 | 4 | export default class StartCommand extends Command { 5 | private server: Server; 6 | 7 | constructor(server: Server) { 8 | super(); 9 | this.server = server; 10 | } 11 | 12 | public execute(): void { 13 | this.server.start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/command/StopCommand.ts: -------------------------------------------------------------------------------- 1 | import Command from "./Command"; 2 | import Server from "./Server"; 3 | 4 | export default class StopCommand extends Command { 5 | private server: Server; 6 | 7 | constructor(server: Server) { 8 | super(); 9 | this.server = server; 10 | } 11 | 12 | public execute(): void { 13 | this.server.stop(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/AbstractExpression.ts: -------------------------------------------------------------------------------- 1 | import Context from "./Context"; 2 | 3 | export default interface AbstractExpression { 4 | interpret(context: Context): void; 5 | } 6 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/Client.ts: -------------------------------------------------------------------------------- 1 | import Parser from "./Parser"; 2 | 3 | const parser = new Parser("3 4 + 2 * 1 +"); 4 | const result = parser.evaluate(); 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/Context.ts: -------------------------------------------------------------------------------- 1 | export default class Context { 2 | tree: number[]; 3 | 4 | constructor () { 5 | this.tree = []; 6 | } 7 | 8 | push (number: number) { 9 | this.tree.push(number); 10 | } 11 | 12 | pop (): number | undefined { 13 | return this.tree.pop(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/MinusExpression.ts: -------------------------------------------------------------------------------- 1 | import AbstractExpression from "./AbstractExpression"; 2 | import Context from "./Context"; 3 | 4 | export default class MinusExpression implements AbstractExpression { 5 | 6 | interpret (context: Context) { 7 | const operand1 = context.pop(); 8 | const operand2 = context.pop(); 9 | if (!operand1 || !operand2) throw new Error("Invalid Operation"); 10 | context.push((operand1 * -1) + operand2); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/MultiplyExpression.ts: -------------------------------------------------------------------------------- 1 | import AbstractExpression from "./AbstractExpression"; 2 | import Context from "./Context"; 3 | 4 | export default class MultiplyExpression implements AbstractExpression { 5 | 6 | interpret (context: Context) { 7 | const operand1 = context.pop(); 8 | const operand2 = context.pop(); 9 | if (!operand1 || !operand2) throw new Error("Invalid Operation"); 10 | context.push(operand1 * operand2); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/NumberExpression.ts: -------------------------------------------------------------------------------- 1 | import AbstractExpression from "./AbstractExpression"; 2 | import Context from "./Context"; 3 | 4 | export default class NumberExpression implements AbstractExpression { 5 | number: number; 6 | 7 | constructor (number: number) { 8 | this.number = number; 9 | } 10 | 11 | interpret (context: Context) { 12 | context.push(this.number); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/Parser.ts: -------------------------------------------------------------------------------- 1 | import AbstractExpression from "./AbstractExpression"; 2 | import Context from "./Context"; 3 | import MinusExpression from "./MinusExpression"; 4 | import MultiplyExpression from "./MultiplyExpression"; 5 | import NumberExpression from "./NumberExpression"; 6 | import PlusExpression from "./PlusExpression"; 7 | 8 | export default class Parser { 9 | tree: AbstractExpression[]; 10 | 11 | constructor (input: string) { 12 | this.tree = []; 13 | 14 | for (const token of input.split(" ")) { 15 | if (token === "+") { 16 | this.tree.push(new PlusExpression()); 17 | continue; 18 | } 19 | if (token === "-") { 20 | this.tree.push(new MinusExpression()); 21 | continue; 22 | } 23 | if (token === "*") { 24 | this.tree.push(new MultiplyExpression()); 25 | continue; 26 | } 27 | this.tree.push(new NumberExpression(parseInt(token))); 28 | } 29 | } 30 | 31 | evaluate () { 32 | const context = new Context(); 33 | for (const e of this.tree) { 34 | e.interpret(context); 35 | } 36 | return context.pop(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/behavioral/interpreter/PlusExpression.ts: -------------------------------------------------------------------------------- 1 | import AbstractExpression from "./AbstractExpression"; 2 | import Context from "./Context"; 3 | 4 | export default class PlusExpression implements AbstractExpression { 5 | 6 | interpret (context: Context) { 7 | const operand1 = context.pop(); 8 | const operand2 = context.pop(); 9 | if (!operand1 || !operand2) throw new Error("Invalid Operation"); 10 | context.push(operand1 + operand2); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/iterator/Client.ts: -------------------------------------------------------------------------------- 1 | import NumberIterator from "./NumberIterator"; 2 | 3 | const array = [1,2,3,4,5,6,7,8,9]; 4 | 5 | const iterator = new NumberIterator(array); 6 | 7 | while (iterator.hasNext()) { 8 | const element = iterator.next(); 9 | console.log(element); 10 | } 11 | -------------------------------------------------------------------------------- /src/behavioral/iterator/Iterator.ts: -------------------------------------------------------------------------------- 1 | export default interface Iterator { 2 | 3 | next(): any; 4 | hasNext(): boolean; 5 | } 6 | -------------------------------------------------------------------------------- /src/behavioral/iterator/NumberIterator.ts: -------------------------------------------------------------------------------- 1 | import Iterator from "./Iterator"; 2 | 3 | export default class NumberIterator implements Iterator { 4 | 5 | private collection: number[] = []; 6 | private position: number = 0; 7 | 8 | constructor(collection: number[]) { 9 | this.collection = collection; 10 | } 11 | 12 | public next(): number { 13 | var result = this.collection[this.position]; 14 | this.position += 1; 15 | return result; 16 | } 17 | 18 | public hasNext(): boolean { 19 | return this.position < this.collection.length; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/behavioral/mediator/Client.ts: -------------------------------------------------------------------------------- 1 | 2 | import Mediator from "./Mediator"; 3 | import User from "./User"; 4 | 5 | const mediator = new Mediator(); 6 | const john = new User("John", mediator); 7 | const clara = new User("Clara", mediator); 8 | const ana = new User("Ana", mediator); 9 | 10 | mediator.addUser(john); 11 | mediator.addUser(clara); 12 | mediator.addUser(ana); 13 | 14 | john.send("Hello everyone!"); 15 | clara.send("Hello John!"); 16 | ana.send("Hi John!"); 17 | -------------------------------------------------------------------------------- /src/behavioral/mediator/Mediator.ts: -------------------------------------------------------------------------------- 1 | import User from "./User"; 2 | 3 | export default class Mediator { 4 | users: User[]; 5 | 6 | constructor () { 7 | this.users = []; 8 | } 9 | 10 | addUser (user: User) { 11 | this.users.push(user); 12 | } 13 | 14 | public send(sender: User, message: string): void { 15 | for (const user of this.users) { 16 | if (user === sender) continue; 17 | user.receive(sender, message); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/behavioral/mediator/User.ts: -------------------------------------------------------------------------------- 1 | import Mediator from "./Mediator"; 2 | 3 | export default class User { 4 | mediator: Mediator; 5 | name: string; 6 | 7 | constructor(name: string, mediator: Mediator) { 8 | this.mediator = mediator; 9 | this.name = name; 10 | } 11 | 12 | public send(message: string): void { 13 | this.mediator.send(this, message); 14 | } 15 | 16 | public receive(sender: User, message: string): void { 17 | console.log(`${this.name} received message ${message} from ${sender.name}`); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/memento/Client.ts: -------------------------------------------------------------------------------- 1 | import Originator from "./Originator"; 2 | 3 | const savedStates = []; 4 | 5 | const originator = new Originator("A"); 6 | savedStates.push(originator.createMemento()); 7 | originator.state = "B"; 8 | savedStates.push(originator.createMemento()); 9 | originator.state = "C"; 10 | savedStates.push(originator.createMemento()); 11 | originator.state = "D"; 12 | savedStates.push(originator.createMemento()); 13 | originator.state = "E"; 14 | savedStates.push(originator.createMemento()); 15 | originator.setMemento(savedStates[0]); 16 | console.log(originator.state); 17 | originator.setMemento(savedStates[1]); 18 | console.log(originator.state); 19 | originator.setMemento(savedStates[2]); 20 | console.log(originator.state); 21 | -------------------------------------------------------------------------------- /src/behavioral/memento/Memento.ts: -------------------------------------------------------------------------------- 1 | export default class Memento { 2 | private _state: string; 3 | 4 | constructor (state: string) { 5 | this._state = state; 6 | } 7 | 8 | get state(): string { 9 | console.log("get memento's state"); 10 | return this._state; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/memento/Originator.ts: -------------------------------------------------------------------------------- 1 | import Memento from "./Memento"; 2 | 3 | export default class Originator { 4 | state: string; 5 | 6 | constructor(state: string) { 7 | this.state = state; 8 | } 9 | 10 | createMemento(): Memento { 11 | console.log("creates a memento with a given state!"); 12 | return new Memento(this.state); 13 | } 14 | 15 | setMemento(memento: Memento) { 16 | console.log("sets the state back"); 17 | this.state = memento.state; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/observer/Button.ts: -------------------------------------------------------------------------------- 1 | import Observer from "./Observer"; 2 | 3 | export default class Button implements Observer { 4 | 5 | update(): void { 6 | console.log("Button was notified"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/behavioral/observer/Client.ts: -------------------------------------------------------------------------------- 1 | import Expression from "./Expression"; 2 | import Button from "./Button"; 3 | import InputText from "./InputText"; 4 | 5 | const inputText = new InputText(); 6 | inputText.register(new Expression()); 7 | inputText.register(new Button()); 8 | inputText.notifyAll(); 9 | -------------------------------------------------------------------------------- /src/behavioral/observer/Expression.ts: -------------------------------------------------------------------------------- 1 | import Observer from "./Observer"; 2 | 3 | export default class Expression implements Observer { 4 | 5 | update(): void { 6 | console.log("Expression was notified"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/behavioral/observer/InputText.ts: -------------------------------------------------------------------------------- 1 | import Observer from "./Observer"; 2 | 3 | export default class InputText { 4 | observers: Observer[]; 5 | 6 | constructor () { 7 | this.observers = []; 8 | } 9 | 10 | register (observer: Observer) { 11 | this.observers.push(observer); 12 | } 13 | 14 | unregister (observer: Observer) { 15 | const position = this.observers.indexOf(observer); 16 | this.observers.splice(position, 1); 17 | } 18 | 19 | notifyAll () { 20 | this.observers.forEach(observer => observer.update()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/behavioral/observer/Observer.ts: -------------------------------------------------------------------------------- 1 | export default interface Observer { 2 | update() : void; 3 | } 4 | -------------------------------------------------------------------------------- /src/behavioral/state/Client.ts: -------------------------------------------------------------------------------- 1 | import StateContext from "./StateContext"; 2 | 3 | const stateContext = new StateContext(); 4 | stateContext.writeName("monday"); 5 | stateContext.writeName("tuesday"); 6 | stateContext.writeName("wednesday"); 7 | stateContext.writeName("thursday"); 8 | stateContext.writeName("friday"); 9 | stateContext.writeName("saturday"); 10 | stateContext.writeName("sunday"); 11 | -------------------------------------------------------------------------------- /src/behavioral/state/LowerCaseState.ts: -------------------------------------------------------------------------------- 1 | import State from "./State"; 2 | import StateContext from "./StateContext"; 3 | import UpperCaseState from "./UpperCaseState"; 4 | 5 | export default class LowerCaseState implements State { 6 | 7 | writeName(context: StateContext, name: string): void { 8 | console.log(name.toLowerCase()); 9 | context.setState(new UpperCaseState()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/behavioral/state/State.ts: -------------------------------------------------------------------------------- 1 | import StateContext from "./StateContext"; 2 | 3 | export default interface State { 4 | writeName (context: StateContext, name: string): void; 5 | } 6 | -------------------------------------------------------------------------------- /src/behavioral/state/StateContext.ts: -------------------------------------------------------------------------------- 1 | import LowerCaseState from "./LowerCaseState"; 2 | import State from "./State"; 3 | 4 | export default class StateContext { 5 | state: State; 6 | 7 | constructor () { 8 | this.state = new LowerCaseState(); 9 | } 10 | 11 | setState (state: State) { 12 | this.state = state; 13 | } 14 | 15 | writeName(name: string) { 16 | this.state.writeName(this, name); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/behavioral/state/UpperCaseState.ts: -------------------------------------------------------------------------------- 1 | import LowerCaseState from "./LowerCaseState"; 2 | import State from "./State"; 3 | import StateContext from "./StateContext"; 4 | 5 | export default class UpperCaseState implements State { 6 | count: number; 7 | 8 | constructor () { 9 | this.count = 0; 10 | } 11 | 12 | writeName(context: StateContext, name: string): void { 13 | console.log(name.toUpperCase()); 14 | this.count++; 15 | if (this.count > 1) { 16 | context.setState(new LowerCaseState()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/strategy/Client.ts: -------------------------------------------------------------------------------- 1 | 2 | import Context from "./Context"; 3 | import RepositoryDatabase from "./RepositoryDatabase"; 4 | import RepositoryMemory from "./RepositoryMemory"; 5 | 6 | const repositoryMemory = new RepositoryMemory(); 7 | const repositoryDatabase = new RepositoryDatabase(); 8 | 9 | const contextMemory = new Context(repositoryMemory); 10 | contextMemory.operation(); 11 | 12 | const contextDatabase = new Context(repositoryDatabase); 13 | contextDatabase.operation(); 14 | -------------------------------------------------------------------------------- /src/behavioral/strategy/Context.ts: -------------------------------------------------------------------------------- 1 | import Entity from "./Entity"; 2 | import Repository from "./Repository"; 3 | 4 | export default class Context { 5 | repository: Repository; 6 | 7 | constructor (repository: Repository) { 8 | this.repository = repository; 9 | } 10 | 11 | operation () { 12 | const entity = new Entity(); 13 | this.repository.save(entity); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/strategy/Entity.ts: -------------------------------------------------------------------------------- 1 | export default class Entity { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/behavioral/strategy/Repository.ts: -------------------------------------------------------------------------------- 1 | import Entity from "./Entity"; 2 | 3 | export default interface Repository { 4 | save(entity: Entity): void; 5 | get(id: number): void; 6 | update(entity: Entity): void; 7 | delete(id: number): void; 8 | count(): number; 9 | } 10 | -------------------------------------------------------------------------------- /src/behavioral/strategy/RepositoryDatabase.ts: -------------------------------------------------------------------------------- 1 | import Entity from "./Entity"; 2 | import Repository from "./Repository"; 3 | 4 | export default class RepositoryDatabase implements Repository { 5 | 6 | save(entity: Entity): void { 7 | console.log("database save entity"); 8 | } 9 | get(id: number): void { 10 | console.log("database get entity"); 11 | } 12 | update(entity: Entity): void { 13 | console.log("database update entity"); 14 | } 15 | delete(id: number): void { 16 | console.log("database delete entity"); 17 | } 18 | count(): number { 19 | console.log("database count entities"); 20 | return 10; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/behavioral/strategy/RepositoryMemory.ts: -------------------------------------------------------------------------------- 1 | import Entity from "./Entity"; 2 | import Repository from "./Repository"; 3 | 4 | export default class RepositoryMemory implements Repository { 5 | 6 | save(entity: Entity): void { 7 | console.log("memory save entity"); 8 | } 9 | get(id: Entity): void { 10 | console.log("memory get entity"); 11 | } 12 | update(entity: Entity): void { 13 | console.log("memory update entity"); 14 | } 15 | delete(id: Entity): void { 16 | console.log("memory delete entity"); 17 | } 18 | count(): number { 19 | console.log("memory count entities"); 20 | return 10; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/behavioral/template_method/Client.ts: -------------------------------------------------------------------------------- 1 | import Item from "./Item"; 2 | import LocalOrder from "./LocalOrder"; 3 | import OnlineOrder from "./OnlineOrder"; 4 | 5 | const item1 = new Item("Lamp", 39); 6 | const item2 = new Item("Racket", 99); 7 | 8 | const localOrder = new LocalOrder(); 9 | localOrder.addItem(item1); 10 | localOrder.addItem(item2); 11 | console.log(localOrder.getTotal()); 12 | 13 | const onlineOrder = new OnlineOrder(); 14 | onlineOrder.addItem(item1); 15 | onlineOrder.addItem(item2); 16 | console.log(onlineOrder.getTotal()); 17 | -------------------------------------------------------------------------------- /src/behavioral/template_method/Item.ts: -------------------------------------------------------------------------------- 1 | export default class Item { 2 | description: string; 3 | price: number; 4 | 5 | constructor (description: string, price: number) { 6 | this.description = description; 7 | this.price = price; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/behavioral/template_method/LocalOrder.ts: -------------------------------------------------------------------------------- 1 | import Order from "./Order"; 2 | 3 | export default class LocalOrder extends Order { 4 | 5 | calculateTax(total: number): number { 6 | return total * 0.3; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/behavioral/template_method/OnlineOrder.ts: -------------------------------------------------------------------------------- 1 | import Order from "./Order"; 2 | 3 | export default class OnlineOrder extends Order { 4 | 5 | calculateTax(total: number): number { 6 | return total * 0.2; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/behavioral/template_method/Order.ts: -------------------------------------------------------------------------------- 1 | import Item from "./Item"; 2 | 3 | export default abstract class Order { 4 | items: Item[]; 5 | 6 | constructor () { 7 | this.items = []; 8 | } 9 | 10 | addItem (item: Item) { 11 | this.items.push(item); 12 | } 13 | 14 | abstract calculateTax (total: number): number; 15 | 16 | getTotal () { 17 | let total = 0; 18 | for (const item of this.items) { 19 | total += item.price; 20 | } 21 | total += this.calculateTax(total); 22 | return total; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Client.ts: -------------------------------------------------------------------------------- 1 | import HolidayTaxVisitor from "./HolidayTaxVisitor"; 2 | import Liquor from "./Liquor"; 3 | import TaxVisitor from "./TaxVisitor"; 4 | import Tobacco from "./Tobacco"; 5 | 6 | const taxVisitor = new TaxVisitor(); 7 | const holidayTaxVisitor = new HolidayTaxVisitor(); 8 | 9 | const liquor = new Liquor(10); 10 | console.log(liquor.accept(taxVisitor)); 11 | console.log(liquor.accept(holidayTaxVisitor)); 12 | 13 | const tobacco = new Tobacco(20); 14 | console.log(tobacco.accept(taxVisitor)); 15 | console.log(tobacco.accept(holidayTaxVisitor)); 16 | -------------------------------------------------------------------------------- /src/behavioral/visitor/HolidayTaxVisitor.ts: -------------------------------------------------------------------------------- 1 | import Product from "./Product"; 2 | import Visitor from "./Visitor"; 3 | 4 | export default class HolidayTaxVisitor implements Visitor { 5 | 6 | visit(product: Product): number { 7 | return product.price * 1.03; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Liquor.ts: -------------------------------------------------------------------------------- 1 | import Product from "./Product"; 2 | import Visitable from "./Visitable"; 3 | import Visitor from "./Visitor"; 4 | 5 | export default class Liquor implements Visitable, Product { 6 | price: number; 7 | 8 | constructor (price: number) { 9 | this.price = price; 10 | } 11 | 12 | accept(visitor: Visitor): void { 13 | return visitor.visit(this); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /src/behavioral/visitor/Product.ts: -------------------------------------------------------------------------------- 1 | export default interface Product { 2 | price: number; 3 | } 4 | -------------------------------------------------------------------------------- /src/behavioral/visitor/TaxVisitor.ts: -------------------------------------------------------------------------------- 1 | import Product from "./Product"; 2 | import Visitor from "./Visitor"; 3 | 4 | export default class TaxVisitor implements Visitor { 5 | 6 | visit(product: Product): number { 7 | return product.price * 1.1; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Tobacco.ts: -------------------------------------------------------------------------------- 1 | import Product from "./Product"; 2 | import Visitable from "./Visitable"; 3 | import Visitor from "./Visitor"; 4 | 5 | export default class Tobacco implements Visitable, Product { 6 | price: number; 7 | 8 | constructor (price: number) { 9 | this.price = price; 10 | } 11 | 12 | accept(visitor: Visitor): void { 13 | return visitor.visit(this); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /src/behavioral/visitor/Visitable.ts: -------------------------------------------------------------------------------- 1 | import Visitor from "./Visitor"; 2 | 3 | export default interface Visitable { 4 | accept(visitor: Visitor): void; 5 | } 6 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Visitor.ts: -------------------------------------------------------------------------------- 1 | import Product from "./Product"; 2 | 3 | export default interface Visitor { 4 | visit(product: Product): void; 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/AbstractFactory.ts: -------------------------------------------------------------------------------- 1 | import OrderRepository from "./OrderRepository"; 2 | import ProductRepository from "./ProductRepository"; 3 | 4 | export default interface AbstractFactory { 5 | createOrderRepository() : OrderRepository; 6 | createProductRepository(): ProductRepository; 7 | } 8 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/Client.ts: -------------------------------------------------------------------------------- 1 | import GetOrder from "./GetOrder"; 2 | import RepositoryMemoryFactory from "./RepositoryMemoryFactory"; 3 | 4 | const memoryFactory = new RepositoryMemoryFactory(); 5 | const getOrder = new GetOrder(memoryFactory); 6 | const order = getOrder.execute(10); 7 | console.log(order); 8 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/GetOrder.ts: -------------------------------------------------------------------------------- 1 | import AbstractFactory from "./AbstractFactory"; 2 | import OrderRepository from "./OrderRepository"; 3 | 4 | export default class GetOrder { 5 | orderRepository: OrderRepository; 6 | 7 | constructor (repositoryFactory: AbstractFactory) { 8 | this.orderRepository = repositoryFactory.createOrderRepository(); 9 | } 10 | 11 | execute (id: number) { 12 | const order = this.orderRepository.get(id); 13 | return order; 14 | } 15 | } -------------------------------------------------------------------------------- /src/creational/abstract_factory/Order.ts: -------------------------------------------------------------------------------- 1 | export default class Order { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/OrderRepository.ts: -------------------------------------------------------------------------------- 1 | import Order from "./Order"; 2 | 3 | export default interface OrderRepository { 4 | get(id: number): Order; 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/OrderRepositoryDatabase.ts: -------------------------------------------------------------------------------- 1 | import Order from "./Order"; 2 | import OrderRepository from "./OrderRepository"; 3 | 4 | export default class OrderRepositoryDatabase implements OrderRepository { 5 | 6 | get(id: number): Order { 7 | throw new Error("Method not implemented."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/OrderRepositoryMemory.ts: -------------------------------------------------------------------------------- 1 | import Order from "./Order"; 2 | import OrderRepository from "./OrderRepository"; 3 | 4 | export default class OrderRepositoryMemory implements OrderRepository { 5 | 6 | get(id: number): Order { 7 | return new Order(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/ProductRepository.ts: -------------------------------------------------------------------------------- 1 | export default interface ProductRepository { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/ProductRepositoryDatabase.ts: -------------------------------------------------------------------------------- 1 | import ProductRepository from "./ProductRepository"; 2 | 3 | export default class ProductRepositoryDatabase implements ProductRepository { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/ProductRepositoryMemory.ts: -------------------------------------------------------------------------------- 1 | import ProductRepository from "./ProductRepository"; 2 | 3 | export default class ProductRepositoryMemory implements ProductRepository { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/RepositoryDatabaseFactory.ts: -------------------------------------------------------------------------------- 1 | import AbstractFactory from "./AbstractFactory"; 2 | import OrderRepository from "./OrderRepository"; 3 | import OrderRepositoryDatabase from "./OrderRepositoryDatabase"; 4 | import ProductRepository from "./ProductRepository"; 5 | import ProductRepositoryDatabase from "./ProductRepositoryDatabase"; 6 | 7 | export default class RepositoryDatabaseFactory implements AbstractFactory { 8 | 9 | createOrderRepository(): OrderRepository { 10 | return new OrderRepositoryDatabase(); 11 | } 12 | createProductRepository(): ProductRepository { 13 | return new ProductRepositoryDatabase(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/creational/abstract_factory/RepositoryMemoryFactory.ts: -------------------------------------------------------------------------------- 1 | import AbstractFactory from "./AbstractFactory"; 2 | import OrderRepository from "./OrderRepository"; 3 | import OrderRepositoryMemory from "./OrderRepositoryMemory"; 4 | import ProductRepository from "./ProductRepository"; 5 | import ProductRepositoryMemory from "./ProductRepositoryMemory"; 6 | 7 | export default class RepositoryMemoryFactory implements AbstractFactory { 8 | 9 | createOrderRepository(): OrderRepository { 10 | return new OrderRepositoryMemory(); 11 | } 12 | createProductRepository(): ProductRepository { 13 | return new ProductRepositoryMemory(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/creational/builder/Client.ts: -------------------------------------------------------------------------------- 1 | import UserBuilder from "./UserBuilder"; 2 | 3 | const user = new UserBuilder("John") 4 | .setAge(18) 5 | .setPhone("99 999999999") 6 | .setAddress("Ocean Dr. 1000") 7 | .build(); 8 | 9 | console.log(user); 10 | -------------------------------------------------------------------------------- /src/creational/builder/User.ts: -------------------------------------------------------------------------------- 1 | import UserBuilder from "./UserBuilder"; 2 | 3 | export default class User { 4 | private name: string; 5 | private age: number | undefined; 6 | private phone: string | undefined; 7 | private address: string | undefined; 8 | 9 | constructor(builder: UserBuilder) { 10 | this.name = builder.Name; 11 | this.age = builder.Age; 12 | this.phone = builder.Phone; 13 | this.address = builder.Address 14 | } 15 | 16 | get Name() { 17 | return this.name; 18 | } 19 | get Age() { 20 | return this.age; 21 | } 22 | get Phone() { 23 | return this.phone; 24 | } 25 | get Address() { 26 | return this.address; 27 | } 28 | } -------------------------------------------------------------------------------- /src/creational/builder/UserBuilder.ts: -------------------------------------------------------------------------------- 1 | import User from "./User"; 2 | 3 | export default class UserBuilder { 4 | private name: string; 5 | private age?: number; 6 | private phone?: string; 7 | private address?: string; 8 | 9 | constructor(name: string) { 10 | this.name = name; 11 | } 12 | 13 | get Name() { 14 | return this.name; 15 | } 16 | setAge(value: number): UserBuilder { 17 | this.age = value; 18 | return this; 19 | } 20 | get Age() { 21 | return this.age; 22 | } 23 | setPhone(value: string): UserBuilder { 24 | this.phone = value; 25 | return this; 26 | } 27 | get Phone() { 28 | return this.phone; 29 | } 30 | setAddress(value: string): UserBuilder { 31 | this.address = value; 32 | return this; 33 | } 34 | get Address() { 35 | return this.address; 36 | } 37 | 38 | build(): User { 39 | return new User(this); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/creational/factory_method/Client.ts: -------------------------------------------------------------------------------- 1 | import MagicMazeGame from "./MagicMazeGame"; 2 | import OrdinaryMazeGame from "./OrdinaryMazeGame"; 3 | 4 | const magicMazeGame = new MagicMazeGame(); 5 | console.log(magicMazeGame.rooms); 6 | 7 | const ordinaryMazeGame = new OrdinaryMazeGame(); 8 | console.log(ordinaryMazeGame.rooms); 9 | -------------------------------------------------------------------------------- /src/creational/factory_method/MagicMazeGame.ts: -------------------------------------------------------------------------------- 1 | import MagicRoom from "./MagicRoom"; 2 | import MazeGame from "./MazeGame"; 3 | import Room from "./Room"; 4 | 5 | export default class MagicMazeGame extends MazeGame { 6 | 7 | makeRoom(): Room { 8 | return new MagicRoom(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/creational/factory_method/MagicRoom.ts: -------------------------------------------------------------------------------- 1 | import Room from "./Room"; 2 | 3 | export default class MagicRoom implements Room { 4 | 5 | connect(room: Room): void { 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/creational/factory_method/MazeGame.ts: -------------------------------------------------------------------------------- 1 | import Room from "./Room"; 2 | 3 | export default abstract class MazeGame { 4 | rooms: Room[]; 5 | 6 | constructor () { 7 | this.rooms = []; 8 | const room1 = this.makeRoom(); 9 | const room2 = this.makeRoom(); 10 | room1.connect(room2); 11 | this.rooms.push(room1); 12 | this.rooms.push(room2); 13 | } 14 | 15 | abstract makeRoom(): Room; 16 | } 17 | -------------------------------------------------------------------------------- /src/creational/factory_method/OrdinaryMazeGame.ts: -------------------------------------------------------------------------------- 1 | import MazeGame from "./MazeGame"; 2 | import OrdinaryRoom from "./OrdinaryRoom"; 3 | import Room from "./Room"; 4 | 5 | export default class OrdinaryMazeGame extends MazeGame { 6 | 7 | makeRoom(): Room { 8 | return new OrdinaryRoom(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/creational/factory_method/OrdinaryRoom.ts: -------------------------------------------------------------------------------- 1 | import Room from "./Room"; 2 | 3 | export default class OrdinaryRoom implements Room { 4 | 5 | connect(room: Room): void { 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/creational/factory_method/Room.ts: -------------------------------------------------------------------------------- 1 | export default interface Room { 2 | connect(room: Room): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/creational/prototype/Client.ts: -------------------------------------------------------------------------------- 1 | import Product from "./Product"; 2 | 3 | const productA = new Product("Lamp", 100); 4 | const productB = productA.clone(); 5 | console.log(productA); 6 | console.log(productB); 7 | -------------------------------------------------------------------------------- /src/creational/prototype/Product.ts: -------------------------------------------------------------------------------- 1 | import Prototype from "./Prototype"; 2 | 3 | export default class Product implements Prototype { 4 | name: string; 5 | price: number; 6 | 7 | constructor (name: string, price: number) { 8 | this.name = name; 9 | this.price = price; 10 | } 11 | 12 | clone(): Prototype { 13 | return new Product(this.name, this.price); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/creational/prototype/Prototype.ts: -------------------------------------------------------------------------------- 1 | export default interface Prototype { 2 | 3 | clone(): Prototype; 4 | } 5 | -------------------------------------------------------------------------------- /src/creational/singleton/Client.ts: -------------------------------------------------------------------------------- 1 | import Singleton from "./Singleton"; 2 | 3 | const singleton1 = Singleton.getInstance(); 4 | const singleton2 = Singleton.getInstance(); 5 | console.log(singleton1); 6 | console.log(singleton2); 7 | -------------------------------------------------------------------------------- /src/creational/singleton/Singleton.ts: -------------------------------------------------------------------------------- 1 | export default class Singleton { 2 | private static instance: Singleton; 3 | uid: number; 4 | 5 | private constructor() { 6 | this.uid = Math.floor(Math.random() * 100); 7 | } 8 | 9 | public static getInstance(): Singleton { 10 | if (!Singleton.instance) { 11 | Singleton.instance = new Singleton(); 12 | } 13 | return Singleton.instance; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/structural/adapter/Client.ts: -------------------------------------------------------------------------------- 1 | import PagSeguroTransaction from "./PagSeguroTransaction"; 2 | import PagSeguroTransactionAdapter from "./PagSeguroTransactionAdapter"; 3 | import PayPalTransaction from "./PayPalTransaction"; 4 | import PayPalTransactionAdapter from "./PayPalTransactionAdapter"; 5 | 6 | const pagSeguroTransaction = new PagSeguroTransaction("AB3HB987HBG7568", 1000, 2); 7 | const transaction1 = new PagSeguroTransactionAdapter(pagSeguroTransaction); 8 | console.log(transaction1); 9 | 10 | const paypalTransaction = new PayPalTransaction("9879", 100, "S"); 11 | const transaction2 = new PayPalTransactionAdapter(paypalTransaction); 12 | console.log(transaction2); -------------------------------------------------------------------------------- /src/structural/adapter/PagSeguroTransaction.ts: -------------------------------------------------------------------------------- 1 | export default class PagSeguroTransaction { 2 | code: string; 3 | grossAmount: number; 4 | status: number; 5 | 6 | constructor (code: string, grossAmount: number, status: number) { 7 | this.code = code; 8 | this.grossAmount = grossAmount; 9 | this.status = status; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/structural/adapter/PagSeguroTransactionAdapter.ts: -------------------------------------------------------------------------------- 1 | import Transaction from "./Transaction"; 2 | import PagSeguroTransaction from "./PagSeguroTransaction"; 3 | 4 | export default class PagSeguroTransactionAdapter implements Transaction { 5 | trackNumber: string; 6 | amount: number; 7 | status: string; 8 | 9 | constructor (pagseguroTransaction: PagSeguroTransaction) { 10 | this.trackNumber = pagseguroTransaction.code; 11 | this.amount = pagseguroTransaction.grossAmount; 12 | this.status = this.convertStatus(pagseguroTransaction.status); 13 | } 14 | 15 | convertStatus(status: number): string { 16 | switch (status) { 17 | case 1: 18 | return "waiting_payment"; 19 | case 2: 20 | return "paid"; 21 | case 3: 22 | return "cancelled"; 23 | default: 24 | return ""; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/structural/adapter/PayPalTransaction.ts: -------------------------------------------------------------------------------- 1 | export default class PayPalTransaction { 2 | id: string; 3 | amount: number; 4 | status: string; 5 | 6 | constructor (id: string, amount: number, status: string) { 7 | this.id = id; 8 | this.amount = amount; 9 | this.status = status; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/structural/adapter/PayPalTransactionAdapter.ts: -------------------------------------------------------------------------------- 1 | import Transaction from "./Transaction"; 2 | import PayPalTransaction from "./PayPalTransaction"; 3 | 4 | export default class PayPalTransactionAdapter implements Transaction { 5 | trackNumber: string; 6 | amount: number; 7 | status: string; 8 | 9 | constructor (paypalTransaction: PayPalTransaction) { 10 | this.trackNumber = paypalTransaction.id; 11 | this.amount = paypalTransaction.amount; 12 | this.status = this.convertStatus(paypalTransaction.status); 13 | } 14 | 15 | convertStatus(status: string): string { 16 | switch (status) { 17 | case "P": 18 | return "waiting_payment"; 19 | case "S": 20 | return "paid"; 21 | case "F": 22 | return "refunded"; 23 | default: 24 | return ""; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/structural/adapter/Transaction.ts: -------------------------------------------------------------------------------- 1 | export default interface Transaction { 2 | trackNumber: string; 3 | amount: number; 4 | status: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/structural/bridge/Abstraction.ts: -------------------------------------------------------------------------------- 1 | import Implementor from "./Implementor"; 2 | 3 | export default abstract class Abstraction { 4 | implementor: Implementor; 5 | 6 | constructor (implementor: Implementor) { 7 | this.implementor = implementor; 8 | } 9 | 10 | abstract operation (): void; 11 | } 12 | -------------------------------------------------------------------------------- /src/structural/bridge/Client.ts: -------------------------------------------------------------------------------- 1 | import ConcreteAbstractionA from "./ConcreteAbstractionA"; 2 | import ConcreteImplementorA from "./ConcreteImplementorA"; 3 | import ConcreteImplementorB from "./ConcreteImplementorB"; 4 | 5 | const concreteImplementorA = new ConcreteImplementorA(); 6 | const concreteImplementorB = new ConcreteImplementorB(); 7 | const abstraction1 = new ConcreteAbstractionA(concreteImplementorA); 8 | abstraction1.operation(); 9 | const abstraction2 = new ConcreteAbstractionA(concreteImplementorB); 10 | abstraction2.operation(); 11 | -------------------------------------------------------------------------------- /src/structural/bridge/ConcreteAbstractionA.ts: -------------------------------------------------------------------------------- 1 | import Abstraction from "./Abstraction"; 2 | 3 | export default class ConcreteAbstractionA extends Abstraction { 4 | 5 | operation(): void { 6 | console.log("A"); 7 | this.implementor.operation(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/bridge/ConcreteImplementorA.ts: -------------------------------------------------------------------------------- 1 | import Implementor from "./Implementor"; 2 | 3 | export default class ConcreteImplementorA implements Implementor { 4 | 5 | constructor () { 6 | 7 | } 8 | 9 | operation(): void { 10 | console.log("A"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/structural/bridge/ConcreteImplementorB.ts: -------------------------------------------------------------------------------- 1 | import Implementor from "./Implementor"; 2 | 3 | export default class ConcreteImplementorA implements Implementor { 4 | 5 | constructor () { 6 | 7 | } 8 | 9 | operation(): void { 10 | console.log("B"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/structural/bridge/Implementor.ts: -------------------------------------------------------------------------------- 1 | export default interface Implementor { 2 | operation (): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/structural/composite/Client.ts: -------------------------------------------------------------------------------- 1 | import Composite from "./Composite"; 2 | import Leaf from "./Leaf"; 3 | 4 | const inputTextName = new Leaf("Name"); 5 | const buttonClose = new Leaf("Close"); 6 | const buttonSave = new Leaf("Save"); 7 | 8 | const dialog = new Composite("Dialog"); 9 | 10 | dialog.add(inputTextName); 11 | dialog.add(buttonClose); 12 | dialog.add(buttonSave); 13 | 14 | const panel = new Composite("Panel"); 15 | panel.add(dialog); 16 | 17 | panel.operation(); 18 | -------------------------------------------------------------------------------- /src/structural/composite/Component.ts: -------------------------------------------------------------------------------- 1 | export default interface Component { 2 | operation(): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/structural/composite/Composite.ts: -------------------------------------------------------------------------------- 1 | import Component from "./Component"; 2 | 3 | export default class Composite implements Component { 4 | 5 | private list: Component[]; 6 | private s: String; 7 | 8 | constructor(s: String) { 9 | this.list = []; 10 | this.s = s; 11 | } 12 | 13 | public operation(): void { 14 | console.log("`operation of `", this.s) 15 | for (var i = 0; i < this.list.length; i += 1) { 16 | this.list[i].operation(); 17 | } 18 | } 19 | 20 | public add(c: Component): void { 21 | this.list.push(c); 22 | } 23 | 24 | public remove(i: number): void { 25 | if (this.list.length <= i) { 26 | throw new Error("index out of bound!"); 27 | } 28 | this.list.splice(i, 1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/structural/composite/Leaf.ts: -------------------------------------------------------------------------------- 1 | import Component from "./Component"; 2 | 3 | export default class Leaf implements Component { 4 | private s: String; 5 | 6 | constructor(s: String) { 7 | this.s = s; 8 | } 9 | 10 | public operation(): void { 11 | console.log("`operation` of Leaf", this.s, " is called."); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/structural/decorator/Client.ts: -------------------------------------------------------------------------------- 1 | import ConcreteComponent from "./ConcreteComponent"; 2 | import ConcreteDecorator from "./ConcreteDecorator"; 3 | 4 | const decorator1 = new ConcreteDecorator(1, new ConcreteComponent("Comp1")); 5 | const decorator2 = new ConcreteDecorator(2, decorator1); 6 | const decorator3 = new ConcreteDecorator(3, decorator2); 7 | decorator1.operation(); 8 | decorator2.operation(); 9 | decorator3.operation(); 10 | -------------------------------------------------------------------------------- /src/structural/decorator/Component.ts: -------------------------------------------------------------------------------- 1 | export default interface Component { 2 | operation(): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/structural/decorator/ConcreteComponent.ts: -------------------------------------------------------------------------------- 1 | import Component from "./Component"; 2 | 3 | export default class ConcreteComponent implements Component { 4 | private s: String; 5 | 6 | constructor(s: String) { 7 | this.s = s; 8 | } 9 | 10 | public operation(): void { 11 | console.log("`operation` of ConcreteComponent", this.s, " is being called!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/structural/decorator/ConcreteDecorator.ts: -------------------------------------------------------------------------------- 1 | import Component from "./Component"; 2 | import Decorator from "./Decorator"; 3 | 4 | export default class ConcreteDecorator extends Decorator { 5 | constructor(id: Number, component: Component) { 6 | super(id, component); 7 | } 8 | 9 | public operation(): void { 10 | super.operation(); 11 | console.log("`operation` of ConcreteDecorator", this.Id, " is being called!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/structural/decorator/Decorator.ts: -------------------------------------------------------------------------------- 1 | import Component from "./Component"; 2 | 3 | export default class Decorator implements Component { 4 | private component: Component; 5 | private id: Number; 6 | 7 | constructor(id: Number, component: Component) { 8 | this.id = id; 9 | this.component = component; 10 | } 11 | 12 | public get Id(): Number { 13 | return this.id; 14 | } 15 | 16 | public operation(): void { 17 | console.log("`operation` of Decorator", this.id, " is being called!"); 18 | this.component.operation(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/structural/facade/Client.ts: -------------------------------------------------------------------------------- 1 | import Facade from "./Facade"; 2 | 3 | const facade = new Facade(); 4 | facade.operationA(); 5 | facade.operationB(); 6 | facade.operationC(); 7 | facade.operationABC(); 8 | -------------------------------------------------------------------------------- /src/structural/facade/Facade.ts: -------------------------------------------------------------------------------- 1 | import ImplementationA from "./ImplementationA"; 2 | import ImplementationB from "./ImplementationB"; 3 | import ImplementationC from "./ImplementationC"; 4 | 5 | export default class Facade { 6 | implementationA: ImplementationA; 7 | implementationB: ImplementationB; 8 | implementationC: ImplementationC; 9 | 10 | constructor () { 11 | this.implementationA = new ImplementationA(); 12 | this.implementationB = new ImplementationB(); 13 | this.implementationC = new ImplementationC(); 14 | } 15 | 16 | operationA () { 17 | this.implementationA.operation(); 18 | } 19 | 20 | operationB () { 21 | this.implementationB.operation(); 22 | } 23 | 24 | operationC () { 25 | this.implementationC.operation(); 26 | } 27 | 28 | operationABC () { 29 | this.implementationA.operation(); 30 | this.implementationB.operation(); 31 | this.implementationC.operation(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/structural/facade/ImplementationA.ts: -------------------------------------------------------------------------------- 1 | export default class ImplementationA { 2 | constructor () { 3 | 4 | } 5 | 6 | operation () { 7 | console.log("Implementation A"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/facade/ImplementationB.ts: -------------------------------------------------------------------------------- 1 | export default class ImplementationB { 2 | constructor () { 3 | 4 | } 5 | 6 | operation () { 7 | console.log("Implementation B"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/facade/ImplementationC.ts: -------------------------------------------------------------------------------- 1 | export default class ImplementationC { 2 | constructor () { 3 | 4 | } 5 | 6 | operation () { 7 | console.log("Implementation C"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/flyweight/Client.ts: -------------------------------------------------------------------------------- 1 | import FlyweightFactory from "./FlyweightFactory"; 2 | 3 | const factory = new FlyweightFactory(); 4 | const conc1 = factory.getFlyweight("conc1"); 5 | const conc2 = factory.getFlyweight("conc2"); 6 | const conc3 = factory.getFlyweight("conc2"); 7 | conc1.operation("1"); 8 | conc2.operation("2"); 9 | conc3.operation("3"); 10 | -------------------------------------------------------------------------------- /src/structural/flyweight/ConcreteFlyweight.ts: -------------------------------------------------------------------------------- 1 | import Flyweight from "./Flyweight"; 2 | 3 | export default class ConcreteFlyweight implements Flyweight { 4 | private instrinsicState: String; 5 | 6 | constructor(instrinsicState: String) { 7 | this.instrinsicState = instrinsicState; 8 | } 9 | 10 | public operation(s: String): void { 11 | console.log("`operation` of ConcreteFlyweight", s, " is being called!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/structural/flyweight/Flyweight.ts: -------------------------------------------------------------------------------- 1 | export default interface Flyweight { 2 | operation(s: String): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/structural/flyweight/FlyweightFactory.ts: -------------------------------------------------------------------------------- 1 | import ConcreteFlyweight from "./ConcreteFlyweight"; 2 | import Flyweight from "./Flyweight"; 3 | 4 | export default class FlyweightFactory { 5 | 6 | private fliesMap: { [s: string]: Flyweight; } = {}; 7 | 8 | constructor() { } 9 | 10 | public getFlyweight(key: string): Flyweight { 11 | 12 | if (this.fliesMap[key] === undefined || null) { 13 | console.log(`Creating the object ${key}`); 14 | this.fliesMap[key] = new ConcreteFlyweight(key); 15 | } 16 | return this.fliesMap[key]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/structural/flyweight/UnsharedConcreteFlyweight.ts: -------------------------------------------------------------------------------- 1 | import Flyweight from "./Flyweight"; 2 | 3 | export default class UnsharedConcreteFlyweight implements Flyweight { 4 | private allState: number; 5 | 6 | constructor(allState: number) { 7 | this.allState = allState; 8 | } 9 | 10 | public operation(s: String): void { 11 | console.log("`operation` of UnsharedConcreteFlyweight", s, " is being called!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/structural/proxy/Client.ts: -------------------------------------------------------------------------------- 1 | import Proxy from "./Proxy"; 2 | 3 | const proxy1 = new Proxy("proxy1"); 4 | const proxy2 = new Proxy("proxy2"); 5 | 6 | proxy1.doAction(); 7 | proxy1.doAction(); 8 | proxy2.doAction(); 9 | proxy2.doAction(); 10 | proxy1.doAction(); 11 | -------------------------------------------------------------------------------- /src/structural/proxy/Proxy.ts: -------------------------------------------------------------------------------- 1 | import RealSubject from "./RealSubject"; 2 | import Subject from "./Subject"; 3 | 4 | export default class Proxy implements Subject { 5 | private realSubject: RealSubject | undefined; 6 | private s: string; 7 | 8 | constructor(s: string) { 9 | this.s = s; 10 | } 11 | 12 | public doAction(): void { 13 | console.log("`doAction` of Proxy(", this.s, ")"); 14 | if (this.realSubject === null || this.realSubject === undefined) { 15 | console.log("creating a new RealSubject."); 16 | this.realSubject = new RealSubject(this.s); 17 | } 18 | this.realSubject.doAction(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/structural/proxy/RealSubject.ts: -------------------------------------------------------------------------------- 1 | import Subject from "./Subject"; 2 | 3 | export default class RealSubject implements Subject { 4 | private s: string; 5 | 6 | constructor(s: string) { 7 | this.s = s; 8 | } 9 | public doAction(): void { 10 | console.log("`doAction` of RealSubject", this.s, "is being called!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/structural/proxy/Subject.ts: -------------------------------------------------------------------------------- 1 | export default interface Subject { 2 | doAction(): void; 3 | } 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | "incremental": true, /* Enable incremental compilation */ 7 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ 8 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 9 | // "lib": [], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ 13 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "./dist", /* Redirect output structure to the directory. */ 18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | // "removeComments": true, /* Do not emit comments to output. */ 22 | // "noEmit": true, /* Do not emit outputs. */ 23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 26 | 27 | /* Strict Type-Checking Options */ 28 | "strict": true, /* Enable all strict type-checking options. */ 29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 30 | // "strictNullChecks": true, /* Enable strict null checks. */ 31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 36 | 37 | /* Additional Checks */ 38 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 43 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ 44 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ 45 | 46 | /* Module Resolution Options */ 47 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 48 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 49 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 50 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 51 | // "typeRoots": [], /* List of folders to include type definitions from. */ 52 | // "types": [], /* Type declaration files to be included in compilation. */ 53 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 54 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 55 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 56 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 57 | 58 | /* Source Map Options */ 59 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 60 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 61 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 62 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 63 | 64 | /* Experimental Options */ 65 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 66 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 67 | 68 | /* Advanced Options */ 69 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 70 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 71 | }, 72 | "include": [ 73 | "src" 74 | ], 75 | "exclude": [ 76 | "node_modules" 77 | ] 78 | } 79 | --------------------------------------------------------------------------------