Design patterns
https://sipios.facebook.com/search/str/paradigm/keywords_search
Creational Patterns
Structural Patterns
Behavioral Patterns
Factory
Builder
Decorator
Proxy
Command
Iterator
Adapter
Facade
Visitor
Observer
Strategy
Design patterns are intrinsic pattern of OOP
- Michael
Component
DecoratorA
DecoratorB
InputStream is = new LineNumberInputStream(
    new BufferedInputStream(
        new FileInputStream(
            "my_awesome_file.secret"
        )
    )
)@Inject()
class PokemonClient extends CrudClient {
    constructor(private http: HttpClient) {
        this.url = "https://pokeapi.co/api/v2/pokemon/"; 
    }
    //Defined in parent class
    get(id: string): Promise<Data> {
        return this.http.get(uri + id);
    }
    //Defined in parent class
    save(data: Data): Promise<Data> {
        return this.http.post(uri, pokemon);
    }
    //Defined in parent class
    update(data: Data): Promise<Data> {
        return this.http.put(uri, pokemon);
    }
    //Defined in parent class
    delete(id: string): Promise<Data> {
        return this.http.delete(uri + id);
    }
}class RetryClient extends CrudClient {
    private client: CrudClient;
    constructor(client: CrudClient) {
        this.client = client;
    }
    
    get(id: string): Promise<Data> {
        const deferred = Promise.defer();
        super.get(id).catch(() => {
            return super.get(id);
        }).then((data) => {
            deferred.resolve(data);
        }).catch((err)) => {
            deferred.reject(err):
        }):
        return deferred.promise;
    }
}class CachedClient extends CrudClient {
    private client: CrudClient;
    private cache: [key: string]: Data; 
    constructor(client: CrudClient) {
        this.client = client;
    }
    get(id: string): Promise<Data> {
        if(cache[id]) {
            return Promise.resolve(cache[id]);
        } else {
            return super.get(id).then((data) => {
                this.cache[id] = data;
                return data;
            })
        }
    }
}class PokemonComponent {
    private client: CrudClient;
    constructor(pokemonClient: PokemonClient) {
        this.client = new CachedClient(pokemonClient);
    }
    
    //....
}
class PokemonRealTimeComponent {
    private client: CrudClient;
    constructor(pokemonClient: PokemonClient) {
        this.client = new RetryClient(pokemonClient);
    }
    
    //....
}