design_patterns_in_typescript 学习
https://github.com/torokmark/design_patterns_in_typescript
Creational
Singleton [A class of which only a single instance can exist.]
class GameMain{
constructor() {
let singleton1 = SingletonPattern.Singleton.getInstance();
let singleton2 = SingletonPattern.Singleton.getInstance();
if(singleton1 === singleton2) {
console.log("two singletons are equivalent");
} else {
console.log("two singletons are not equivalent");
}
}
}
namespace SingletonPattern {
export class Singleton {
// A variable which stores the singleton object.Initially,
// the variable acts like a placeholder
private static singleton: Singleton;
// private constructor so that no instance is created
private constructor() {
}
// This is how we create a singleton object
public static getInstance(): Singleton {
// check if an instance of the class is already created
if(!Singleton.singleton) {
// if not created,create an instance of the class
// store the instance in the variable
Singleton.singleton = new Singleton();
}
// return the singleton object
return Singleton.singleton;
}
}
}
new GameMain();
Abstract Factory [Creates an instance of several families of classes.]
class GameMain{
constructor() {
let factory1:AbstractFactoryPattern.IAbstractFactory = new AbstractFactoryPattern.ConcreteFactory1();
let test1:AbstractFactoryPattern.Tester = new AbstractFactoryPattern.Tester(factory1);
test1.test();
let factory2:AbstractFactoryPattern.IAbstractFactory = new AbstractFactoryPattern.ConcreteFactory2();
let test2:AbstractFactoryPattern.Tester = new AbstractFactoryPattern.Tester(factory2);
test2.test();
}
}
namespace AbstractFactoryPattern {
export interface IAbstractProductA {
methodA():string;
}
export interface IAbstractProductB {
methodB():number;
}
export interface IAbstractFactory {
createProductA(param?:any):IAbstractProductA;
createProductB():IAbstractProductB;
}
export class ProductA1 implements IAbstractProductA {
methodA = () => {
return "This is methodA of ProductA1";
}
}
export class ProductB1 implements IAbstractProductB {
methodB = () => {
;
}
}
export class ProductA2 implements IAbstractProductA {
methodA = () => {
return "This is methodA of ProductA2";
}
}
export class ProductB2 implements IAbstractProductB {
methodB = () => {
;
}
}
export class ConcreteFactory1 implements IAbstractFactory {
createProductA(param?:any):IAbstractProductA {
return new ProductA1();
}
createProductB():IAbstractProductB {
return new ProductB1();
}
}
export class ConcreteFactory2 implements IAbstractFactory {
createProductA(param?:any):IAbstractProductA {
return new ProductA2();
}
createProductB():IAbstractProductB {
return new ProductB2();
}
}
export class Tester {
private abstractProductA:IAbstractProductA;
private abstractProductB:IAbstractProductB;
constructor(factory:IAbstractFactory) {
this.abstractProductA = factory.createProductA();
this.abstractProductB = factory.createProductB();
}
public test():void {
console.log(this.abstractProductA.methodA());
console.log(this.abstractProductB.methodB());
}
}
}
new GameMain();
Factory Method [Facilitates the creation of other objects.]
class GameMain{
constructor() {
let a:FactoryMethodPattern.IAbstractProduct = FactoryMethodPattern.ProductFactory.createProduct("A");
let b:FactoryMethodPattern.IAbstractProduct = FactoryMethodPattern.ProductFactory.createProduct("B");
console.log(a.method());
console.log(b.method());
}
}
namespace FactoryMethodPattern {
export interface IAbstractProduct {
method(param?:any):void;
}
export class ConcreteProductA implements IAbstractProduct {
method = (param?:any) => {
return "Method of ConcreteProductA";
}
}
export class ConcreteProductB implements IAbstractProduct {
method = (param?:any) => {
return "Method of ConcreteProductB";
}
}
export namespace ProductFactory {
export function createProduct(type:string):IAbstractProduct {
if(type === "A") {
return new ConcreteProductA();
} else if(type === "B") {
return new ConcreteProductB();
}
return null;
}
}
}
new GameMain();
Builder [Solves the problem of telescoping constructor.]
class GameMain{
constructor() {
let u:BuilderPattern.User = new BuilderPattern.UserBuilder("Jancsi")
.setAge()
.setPhone(")
.setAddress("asdf")
.build();
console.log(u.Name + " " + u.Age + " " + u.Phone + " " + u.Address);
}
}
namespace BuilderPattern {
export class UserBuilder {
private name:string;
private age:number;
private phone:string;
private address:string;
constructor(name:string) {
this.name = name;
}
get Name() {
return this.name;
}
setAge(value:number):UserBuilder {
this.age = value;
return this;
}
get Age() {
return this.age;
}
setPhone(value:string):UserBuilder {
this.phone = value;
return this;
}
get Phone() {
return this.phone;
}
setAddress(value:string):UserBuilder {
this.address = value;
return this;
}
get Address() {
return this.address;
}
build():User {
return new User(this);
}
}
export class User {
private name:string;
private age:number;
private phone:string;
private address:string;
constructor(builder:UserBuilder) {
this.name = builder.Name;
this.age = builder.Age;
this.phone = builder.Phone;
this.address = builder.Address;
}
get Name() {
return this.name;
}
get Age() {
return this.age;
}
get Phone() {
return this.phone;
}
get Address() {
return this.address;
}
}
}
new GameMain();
Prototype
class GameMain{
constructor() {
let builder:PrototypePattern.Builder = new PrototypePattern.Builder();
; i <= ; i += ) {
console.log(builder.createOne("c" + i).toString());
}
}
}
namespace PrototypePattern {
export interface IPrototype {
clone():IPrototype;
toString():string;
}
export class Concrete1 implements IPrototype {
clone():IPrototype {
return new Concrete1();
}
toString():string {
return "This is Concrete1";
}
}
export class Concrete2 implements IPrototype {
clone():IPrototype {
return new Concrete2();
}
toString():string {
return "This is Concrete2";
}
}
export class Concrete3 implements IPrototype {
clone():IPrototype {
return new Concrete3();
}
toString():string {
return "This is Concrete3";
}
}
export class Builder {
private prototypeMap: { [s:string]:IPrototype;} = {};
constructor() {
this.prototypeMap['c1'] = new Concrete1();
this.prototypeMap['c2'] = new Concrete2();
this.prototypeMap['c3'] = new Concrete3();
}
createOne(s:string):IPrototype {
console.log(s);
return this.prototypeMap[s].clone();
}
}
}
new GameMain();
Structural Patterns
Adapter [Convert the interface of class into another interface clients expect. Adapter lets class work together that couldn't otherwise because of incompatible interfaces.]
class GameMain{
constructor() {
let adapter:AdapterPattern.Adapter = new AdapterPattern.Adapter();
adapter.call();
}
}
namespace AdapterPattern {
export class Adaptee {
public method():void {
console.log("'method' of Adaptee is being called");
}
}
export interface ITarget {
call():void
}
export class Adapter implements ITarget {
public call():void {
console.log("Adapter's 'call' method is being called");
let adaptee:Adaptee = new Adaptee();
adaptee.method();
}
}
}
new GameMain();
Bridge [decouple an abstraction from its implementation so that the two can vary independently.]
class GameMain{
constructor() {
let abstractionA:BridgePattern.Abstraction = new BridgePattern.RefinedAbstractionA(new BridgePattern.ConcreteImplementorA());
let abstractionB:BridgePattern.Abstraction = new BridgePattern.RefinedAbstractionB(new BridgePattern.ConcreteImplementorB());
abstractionA.callIt("abstractionA");
abstractionB.callIt("abstractionB");
}
}
namespace BridgePattern {
export class Abstraction {
implementor:IImplementor;
constructor(imp:IImplementor) {
this.implementor = imp;
}
public callIt(s:string):void {
throw new Error("This method is abstract!");
}
}
export class RefinedAbstractionA extends Abstraction {
constructor(imp:IImplementor) {
super(imp)
}
public callIt(s:string):void {
console.log("This is RefinedAbstractionA");
this.implementor.callee(s);
}
}
export class RefinedAbstractionB extends Abstraction {
constructor(imp:IImplementor) {
super(imp);
}
public callIt(s:string):void {
console.log("This is RefinedAbstractionB");
this.implementor.callee(s);
}
}
export interface IImplementor {
callee(s:any):void;
}
export class ConcreteImplementorA implements IImplementor {
public callee(s:any):void {
console.log("'callee' of ConcreteImplementorA is being called.");
console.log(s);
}
}
export class ConcreteImplementorB implements IImplementor {
public callee(s:any):void {
console.log("'callee' of ConcreteImplementorB is being called.");
console.log(s);
}
}
}
new GameMain();
Composite [lets clients treat individual objects and compositions uniformly.]
class GameMain{
constructor() {
let leaf1 = ");
let leaf2 = ");
let leaf3 = ");
let composite1 = new CompositePattern.Composite("Comp1");
let composite2 = new CompositePattern.Composite("Comp2");
composite1.add(leaf1);
composite1.add(leaf2);
composite1.add(leaf3);
composite1.remove();
composite2.add(leaf1);
composite2.add(leaf3);
composite1.operation();
composite2.operation();
}
}
namespace CompositePattern {
export interface IComponent {
operation():void;
}
export class Composite implements IComponent {
private list:Array<IComponent>;
private s:string;
constructor(s:string) {
this.list = new Array<IComponent>();
this.s = s;
}
public operation():void {
console.log("'operation' of ",this.s);
; i < this.list.length; i++) {
this.list[i].operation();
}
}
public add(c:IComponent):void {
this.list.push(c);
}
public remove(i:number):void {
if(this.list.length <= i) {
throw new Error("index out of boud!");
}
);
}
}
export class Leaf implements IComponent {
private s:string;
constructor(s:string) {
this.s = s;
}
public operation():void {
console.log("'operation' of Leaf",this.s," is called.");
}
}
}
new GameMain();
Decorator [Allows behavior to be added to an individual object dynamically.]
class GameMain{
constructor() {
let decorator1:DecoratorPattern.Decorator = ,new DecoratorPattern.ConcreteComponent("Component1"));
decorator1.operation();
}
}
namespace DecoratorPattern {
export interface IComponent {
operation():void;
}
export class ConcreteComponent implements IComponent {
private s:string;
constructor(s:string) {
this.s = s;
}
public operation():void {
console.log("'operation' of ConcreteComponent",this.s," is being called!");
}
}
export class Decorator implements IComponent {
private component:IComponent;
private id:number;
constructor(id:number,component:IComponent) {
this.id = id;
this.component = component;
}
public get Id():number {
return this.id;
}
public operation():void {
this.component.operation();
console.log("'operation' of Decorator",this.id," is being called!");
}
}
export class ConcreteDecorator extends Decorator {
constructor(id:number,component:IComponent) {
super(id,component);
}
public operation():void {
super.operation();
console.log("'operation' of ConcreteDecorator",this.Id," is being called!");
}
}
}
new GameMain();
Facade [Substitute the interfaces of a set of classes by the interface of one class. Facade hides implementation classes behind one interface.]
class GameMain{
constructor() {
let facade:FacadePattern.Facade = new FacadePattern.Facade();
facade.operation1();
facade.operation2();
}
}
namespace FacadePattern {
export class Part1 {
public method1():void {
console.log("'method1' of Part1");
}
}
export class Part2 {
public method2():void {
console.log("'method2' of Part2");
}
}
export class Part3 {
public method3():void {
console.log("'method3' of Part3" );
}
}
export class Facade {
private part1:Part1 = new Part1();
private part2:Part2 = new Part2();
private part3:Part3 = new Part3();
public operation1():void {
console.log("'operation1' is called ===");
this.part1.method1();
this.part2.method2();
console.log("=======================");
}
public operation2():void {
console.log("'operation2' is called ===");
this.part1.method1();
this.part3.method3();
console.log("===========================");
}
}
}
new GameMain();
Flyweight [Facilitates the reuse of many fine grained objects, making the utilization of large numbers of objects more efficient.]
class GameMain{
constructor() {
let factory:FlyweightPattern.FlyweightFactory = new FlyweightPattern.FlyweightFactory();
let concrete1:FlyweightPattern.ConcreteFlyweight = <FlyweightPattern.ConcreteFlyweight>factory.getFlyweight("concrete1");
let concrete2:FlyweightPattern.ConcreteFlyweight = <FlyweightPattern.ConcreteFlyweight>factory.getFlyweight("concrete2");
concrete1.operation(");
concrete2.operation(");
}
}
namespace FlyweightPattern {
export interface IFlyweight {
operation(s:string):void;
}
export class ConcreteFlyweight implements IFlyweight {
private intrinsicState:string;
constructor(intrinsicState:string) {
this.intrinsicState = intrinsicState;
}
public operation(s:string):void {
console.log("'operation' of ConcreteFlyweight",s," is being called!");
}
}
export class UnsharedConcreteFlyweight implements IFlyweight {
private allState:number;
constructor(allState:number) {
this.allState = allState;
}
public operation(s:string):void {
console.log("'operation' of UnsharedConcreteFlyweight",s," is being called!");
}
}
export class FlyweightFactory {
private filesMap:{[s:string]:IFlyweight;} = <any>{};
constructor() {
}
public getFlyweight(key:string):IFlyweight {
if(this.filesMap[key] == undefined || null) {
this.filesMap[key] = new ConcreteFlyweight(key);
}
return this.filesMap[key];
}
}
}
new GameMain();
Proxy [Provide a surrogate or placeholder for another object to control access to it.]
class GameMain{
constructor() {
let proxy1:ProxyPattern.Proxy = new ProxyPattern.Proxy("proxy1");
let proxy2:ProxyPattern.Proxy = new ProxyPattern.Proxy("proxy2");
proxy1.doAction();
proxy1.doAction();
proxy2.doAction();
proxy2.doAction();
proxy1.doAction();
}
}
namespace ProxyPattern {
export interface ISubject {
doAction():void;
}
export class RealSubject implements ISubject {
private s:string;
constructor(s:string) {
this.s = s;
}
public doAction():void {
console.log("'doAction' of RealSubject",this.s," is being called!");
}
}
export class Proxy implements ISubject {
private realSubject:RealSubject;
private s:string;
constructor(s:string) {
this.s = s;
}
public doAction():void {
console.log("'doAction' of Proxy(",this.s,")");
if(this.realSubject === null || this.realSubject === undefined) {
console.log("creating a new RealSubject.");
this.realSubject = new RealSubject(this.s);
}
this.realSubject.doAction();
}
}
}
new GameMain();
Behavioral Patterns
Chain of Responsibility [Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.]
class GameMain{
constructor() {
let h1:ChainOfResponsibilityPattern.Handler = );
let h2:ChainOfResponsibilityPattern.Handler = );
let h3:ChainOfResponsibilityPattern.Handler = );
let reqs:Array<number> = [,,,,,,,];
h1.setHandler(h2);
h2.setHandler(h3);
,max = reqs.length; i < max; i++) {
h1.operation("operation is fired!",reqs[i]);
}
}
}
namespace ChainOfResponsibilityPattern {
export class Handler {
private handler:Handler;
private req:number;
constructor(req:number){
this.req = req;
}
public setHandler(handler:Handler):void {
this.handler = handler;
}
public operation(msg:string,req:number):void {
if(req <= this.req) {
this.handlerRequest(msg);
} else if(this.handler !== null && this.handler !== undefined) {
this.handler.operation(msg,req);
}
}
public handlerRequest(msg:string):void {
throw new Error("Abstract method!");
}
}
export class ConcreteHandler1 extends Handler {
constructor(req:number) {
super(req);
}
public handlerRequest(msg:string) {
console.log("Message (ConcreteHandler1) :: ",msg);
}
}
export class ConcreteHandler2 extends Handler {
constructor(req:number) {
super(req);
}
public handlerRequest(msg:string) {
console.log("Message (ConcreteHandler2) :: ",msg);
}
}
export class ConcreteHandler3 extends Handler {
constructor(req:number) {
super(req);
}
public handlerRequest(msg:string) {
console.log("Message (ConcreteHandler3) :: ",msg);
}
}
}
new GameMain();
Command [Creates objects which encapsulate actions and parameters.]
class GameMain{
constructor() {
let receiver:CommandPattern.Receiver = new CommandPattern.Receiver();
let command1:CommandPattern.Command = new CommandPattern.ConcreteCommand1(receiver);
let command2:CommandPattern.Command = new CommandPattern.ConcreteCommand2(receiver);
let invoker:CommandPattern.Invoker = new CommandPattern.Invoker();
invoker.storeAndExecute(command1);
invoker.storeAndExecute(command2);
}
}
namespace CommandPattern {
export class Command {
public execute():void {
throw new Error("Abstract method!");
}
}
export class ConcreteCommand1 extends Command {
private receiver:Receiver;
constructor(receiver:Receiver) {
super();
this.receiver = receiver;
}
public execute():void {
console.log("'execute' method of ConcreteCommand1 is being called!");
this.receiver.action();
}
}
export class ConcreteCommand2 extends Command {
private receiver:Receiver;
constructor(receiver:Receiver) {
super();
this.receiver = receiver;
}
public execute():void {
console.log("'execute' method of ConcreteCommand2 is being called!");
this.receiver.action();
}
}
export class Invoker {
private commands:Command[];
constructor() {
this.commands = [];
}
public storeAndExecute(cmd:Command) {
this.commands.push(cmd);
cmd.execute();
}
}
export class Receiver {
public action():void {
console.log("action is being called!");
}
}
}
new GameMain();
Interpreter [Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.]
class GameMain{
constructor() {
let context:InterpreterPattern.Context = new InterpreterPattern.Context();
let list = [];
list.push(new InterpreterPattern.NonterminalExpression());
list.push(new InterpreterPattern.NonterminalExpression());
list.push(new InterpreterPattern.NonterminalExpression());
list.push(new InterpreterPattern.TerminalExpresss());
list.push(new InterpreterPattern.NonterminalExpression());
list.push(new InterpreterPattern.NonterminalExpression());
list.push(new InterpreterPattern.TerminalExpresss());
list.push(new InterpreterPattern.TerminalExpresss());
,max = list.length;i < max;i++) {
list[i].interpret(context);
}
}
}
namespace InterpreterPattern {
export class Context {
}
export interface IAbstractExpression {
interpret(context:Context):void;
}
export class TerminalExpresss implements IAbstractExpression {
public interpret(context:Context):void {
console.log("'interpret' method of TerminalExpression is being called!");
}
}
export class NonterminalExpression implements IAbstractExpression {
public interpret(context:Context):void {
console.log("'interpret' method of NonterminalExpression is being called!");
}
}
}
new GameMain();
Iterator [Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.]
class GameMain{
constructor() {
let nArray = [,,,,,,,,];
let numbers:IteratorPattern.Numbers = new IteratorPattern.Numbers(nArray);
let it:IteratorPattern.ConcreteIterator = <IteratorPattern.ConcreteIterator>numbers.createIIterator();
while(it.hasNext()){
console.log(it.next());
}
}
}
namespace IteratorPattern {
export interface IIterator {
next():any;
hasNext():boolean;
}
export interface IAggregator {
createIIterator():IIterator;
}
export class ConcreteIterator implements IIterator {
private collection:any[] = [];
;
constructor(collection:any[]) {
this.collection = collection;
}
public next():any {
let result = this.collection[this.position];
this.position ++;
return result;
}
public hasNext():boolean {
return this.position < this.collection.length;
}
}
export class Numbers implements IAggregator {
private collection:number[] = [];
constructor(collection:number[]) {
this.collection = collection;
}
public createIIterator():IIterator {
return new ConcreteIterator(this.collection);
}
}
}
new GameMain();
Mediator [Promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.]
class GameMain{
constructor() {
let cm:MediatorPattern.ConcreteMediator = new MediatorPattern.ConcreteMediator();
let c1:MediatorPattern.ConcreteColleagueA = new MediatorPattern.ConcreteColleagueA(cm);
let c2:MediatorPattern.ConcreteColleagueB = new MediatorPattern.ConcreteColleagueB(cm);
cm.conreteColleagueA = c1;
cm.conreteColleagueB = c2;
c1.send("'send' of ConcreteColleaugeA is being called!");
c2.send("'send' of ConcreteColleagueB is being called!");
}
}
namespace MediatorPattern {
export interface IMediator {
send(msg:string,colleague:Colleague):void;
}
export class Colleague {
public mediator:IMediator;
constructor(mediator:IMediator) {
this.mediator = mediator;
}
public send(msg:string):void {
throw new Error("Abstract Method!");
}
public receive(msg:string):void {
throw new Error("Abstract Method!");
}
}
export class ConcreteColleagueA extends Colleague {
constructor(mediator:IMediator) {
super(mediator)
}
public send(msg:string):void {
this.mediator.send(msg,this);
}
public receive(msg:string):void {
console.log(msg,"'receive' of ConcreteColleagueA is being called!");
}
}
export class ConcreteColleagueB extends Colleague {
constructor(mediator:IMediator) {
super(mediator)
}
public send(msg:string):void {
this.mediator.send(msg,this)
}
public receive(msg:string):void {
console.log(msg,"'receive' of ConcreteColleagueB is being called!");
}
}
export class ConcreteMediator implements IMediator {
public conreteColleagueA:ConcreteColleagueA;
public conreteColleagueB:ConcreteColleagueB;
public send(msg:string,colleague:Colleague):void {
if(this.conreteColleagueA === colleague) {
this.conreteColleagueA.receive(msg);
} else {
this.conreteColleagueB.receive(msg);
}
}
}
}
new GameMain();
Memento [Capture an object’s internal state and externalize it so that it can be restored to that state later.]
class GameMain{
constructor() {
let state:MementoPattern.State = new MementoPattern.State("...State ");
let originator:MementoPattern.Originator = new MementoPattern.Originator(state);
let careTaker:MementoPattern.CareTaker = new MementoPattern.CareTaker();
careTaker.Memento = originator.createMemento();
originator.State = new MementoPattern.State("something else...");
originator.setMemento(careTaker.Memento);
}
}
namespace MementoPattern {
export class State {
private str:string;
constructor(str:string) {
this.str = str;
}
get Str():string {
return this.str;
}
set Str(str:string) {
this.str = str;
}
}
export class Originator {
private state:State;
constructor(state:State) {
this.state = state;
}
get State():State {
return this.state;
}
set State(state:State) {
console.log("State :: ",state);
this.state = state;
}
public createMemento():Memento {
console.log("creates a memento with a given state!");
return new Memento(this.state)
}
public setMemento(memento:Memento) {
console.log("sets the state back");
this.State = memento.State;
}
}
export class Memento {
private state:State;
constructor(state:State) {
this.state = state;
}
get State():State {
console.log("get memento's state");
return this.state;
}
}
export class CareTaker {
private memento:Memento;
get Memento():Memento {
return this.memento;
}
set Memento(memento:Memento) {
this.memento = memento;
}
}
}
new GameMain();
Observer [Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.]
class GameMain{
constructor() {
let sub:ObserverPattern.ConcreteSubject = new ObserverPattern.ConcreteSubject();
sub.register(new ObserverPattern.ConcreteObserver(sub,"Jancsi"));
sub.register(new ObserverPattern.ConcreteObserver(sub,"Julcsa"));
sub.register(new ObserverPattern.ConcreteObserver(sub,"Marcsa"));
sub.SubjectState = ;
sub.notify();
}
}
namespace ObserverPattern {
export class Subject {
private observers:Observer[] = [];
public register(observer:Observer):void {
console.log(observer,"is pushed!");
this.observers.push(observer);
}
public unregister(observer:Observer):void {
let n:number = this.observers.indexOf(observer);
console.log(observer,"is removed");
);
}
public notify():void {
console.log("notify all the observers",this.observers);
,max = this.observers.length;i < max;i++) {
this.observers[i].notify();
}
}
}
export class ConcreteSubject extends Subject {
private subjectState:number;
get SubjectState():number {
return this.subjectState;
}
set SubjectState(subjectState:number) {
this.subjectState = subjectState;
}
}
export class Observer {
public notify():void {
throw new Error("Abstract Method!");
}
}
export class ConcreteObserver extends Observer {
private name:string;
private state:number;
private subject:ConcreteSubject;
constructor(subject:ConcreteSubject,name:string) {
super();
console.log("ConcreteObserver",name,"is created!");
this.subject = subject;
this.name = name;
}
public notify():void {
console.log("ConcreteObserver's notify method");
this.state = this.subject.SubjectState;
console.log(this.name,this.state);
}
get Subject():ConcreteSubject {
return this.subject;
}
set Subject(subject:ConcreteSubject){
this.subject = subject;
}
}
}
new GameMain();
State [A cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements.]
class GameMain{
constructor() {
let context:StatePattern.Context = new StatePattern.Context(new StatePattern.ConcreteStateA());
context.request();
context.request();
context.request();
context.request();
context.request();
context.request();
context.request();
context.request();
}
}
namespace StatePattern {
export interface IState {
handle(context:Context):void;
}
export class ConcreteStateA implements IState {
public handle(context:Context):void {
console.log("'handle' method of ConcreteStateA is being called!");
context.State = new ConcreteStateB();
}
}
export class ConcreteStateB implements IState {
public handle(context:Context):void {
console.log("'handle' method of ConcreteStateB is being called!");
context.State = new ConcreteStateA();
}
}
export class Context {
private state:IState;
constructor(state:IState) {
this.state = state;
}
get State():IState {
return this.state;
}
set State(state:IState) {
this.state = state;
}
public request():void {
console.log("request is being called!");
this.state.handle(this);
}
}
}
new GameMain();
Strategy [Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.]
class GameMain{
constructor() {
let context:StrategyPattern.Context = new StrategyPattern.Context(new StrategyPattern.ConcreteStrategy1());
context.executeStrategy();
context = new StrategyPattern.Context(new StrategyPattern.ConcreteStrategy2());
context.executeStrategy();
context = new StrategyPattern.Context(new StrategyPattern.ConcreteStrategy3());
context.executeStrategy();
}
}
namespace StrategyPattern {
export interface IStrategy {
execute():void
}
export class ConcreteStrategy1 implements IStrategy {
public execute():void {
console.log("'execute' method of ConcreteStrategy1 is being called.");
}
}
export class ConcreteStrategy2 implements IStrategy {
public execute():void {
console.log("'execute' method of ConcreteStrategy2 is being called.");
}
}
export class ConcreteStrategy3 implements IStrategy {
public execute():void {
console.log("'execute' method of ConcreteStrategy3 is being called.");
}
}
export class Context {
private strategy:IStrategy;
constructor(strategy:IStrategy){
this.strategy = strategy;
}
public executeStrategy():void {
this.strategy.execute();
}
}
}
new GameMain();
Template Method [Define the basic steps of an algorithm and allow the implementation of the individual steps to be changed.]
class GameMain{
constructor() {
let c1:TemplateMethodPattern.ConcreteClass1 = new TemplateMethodPattern.ConcreteClass1();
let c2:TemplateMethodPattern.ConcreteClass2 = new TemplateMethodPattern.ConcreteClass2();
c1.templateMethod();
c2.templateMethod();
}
}
namespace TemplateMethodPattern {
export class AbstractClass {
public method1():void {
throw new Error("Abstract Method");
}
public method2():void {
throw new Error("Abstract Method");
}
public method3():void {
throw new Error("Abstract Method");
}
public templateMethod():void {
console.log("templateMethod is being called");
this.method1();
this.method2();
this.method3();
}
}
export class ConcreteClass1 extends AbstractClass {
public method1():void {
console.log("method1 of ConcreteClass1");
}
public method2():void {
console.log("method2 of ConcreteClass1");
}
public method3():void {
console.log("method3 of ConcreteClass1");
}
}
export class ConcreteClass2 extends AbstractClass {
public method1():void {
console.log("method1 of ConcreteClass2");
}
public method2():void {
console.log("method2 of ConcreteClass2");
}
public method3():void {
console.log("method3 of ConcreteClass2");
}
}
}
new GameMain();
Visitor [Allows for one or more operation to be applied to a set of objects at runtime, decoupling the operations from the object structure.]
class GameMain{
constructor() {
let objs:VisitorPattern.Objs = new VisitorPattern.Objs();
objs.attach(new VisitorPattern.ConcreteElement1());
objs.attach(new VisitorPattern.ConcreteElement2());
let v1:VisitorPattern.ConcreteVisitor1 = new VisitorPattern.ConcreteVisitor1();
let v2:VisitorPattern.ConcreteVisitor2 = new VisitorPattern.ConcreteVisitor2();
objs.operate(v1);
objs.operate(v2);
}
}
namespace VisitorPattern {
export interface IVisitor {
visitConcreteElement1(concreteElement1:ConcreteElement1):void;
visitConcreteElement2(concreteElement2:ConcreteElement2):void;
}
export class ConcreteVisitor1 implements IVisitor {
public visitConcreteElement1(concreteElement1:ConcreteElement1):void {
console.log("'visitConcreteElement1' of ConcreteVisitor1 is being called!");
}
public visitConcreteElement2(concreteElement2:ConcreteElement2):void {
console.log("'visitConcreteElement2' of ConcreteVisitro1 is being called!");
}
}
export class ConcreteVisitor2 implements IVisitor {
public visitConcreteElement1(concreteElement1:ConcreteElement1):void {
console.log("'visitConcreteElement1' of ConcreteVisitor2 is being called!");
}
public visitConcreteElement2(concreteElement2:ConcreteElement2):void {
console.log("'visitConcreteElement2' of ConcreteVisitor2 is being called!");
}
}
export interface IElement {
operate(visitor:IVisitor):void;
}
export class ConcreteElement1 implements IElement {
public operate(visitor:IVisitor):void {
console.log("'operate' of ConcreteElement1 is being called!");
visitor.visitConcreteElement1(this);
}
}
export class ConcreteElement2 implements IElement {
public operate(visitor:IVisitor):void {
console.log("'operate' of ConcreteElement2 is being called!");
visitor.visitConcreteElement2(this);
}
}
export class Objs {
private elements:IElement[] = [];
public attach(e:IElement):void {
this.elements.push(e);
}
public detach(e:IElement):void {
let index = this.elements.indexOf(e);
);
}
public operate(visitor:IVisitor):void {
,max = this.elements.length;i < max;i++) {
this.elements[i].operate(visitor);
}
}
}
}
new GameMain();
design_patterns_in_typescript 学习的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
随机推荐
- Pandas 基础(11) - 用 melt 做格式转换
melt 也可以用来做数据格式转换, 请看下图, 我们可以用 melt 把左表转成右表的格式: 首先引入文件(已上传): df = pd.read_csv('/Users/rachel/Sites/p ...
- 读写方式 r , r+ , w , w+ , a , a+
r只读,r+读写,不创建:r+:可读可写,若文件不存在,报错 w如果文件已经存在,则不替换: w 就是打开文件,文件如果不存在,就会新建一个文件: w+: 可读可写,若文件不存在,创建 信息来源:ht ...
- C# 虹软离线SDK引擎 人脸识别
一,背景 整体来说虹软的人脸识别SDK还是不错的.我们测试过Face++的,百度的,腾讯的,都是在线联网的,需要把上传数据到它们服务器,不利商业用途:虹软SDK支持离线. 二,下载虹软SDK 1.注册 ...
- DAY11 函数(二)
一.函数的对象 1.1定义:函数名就是存放了函数的内存地址,存放了内存地址的变量都是对象,即 函数名 就是 函数对象 1.2函数对象的应用 1 可以直接被引用 fn = cp_fn def fn(): ...
- double 类型转化为Integer
(1)把double先转化成int类型 Double reseve3=Double.parseDouble(bddet[0].getReserve3()); int b=reseve3.intValu ...
- ionic3开发ios端
ionic框架是一端开发,三端适用(android端,ios端,web端),意思是在其中一端开发的代码,拿到另外两端,代码同样生效 那现在就说一下在web端开发拿到ios端开发前需要做的事情 开发io ...
- Oracle数据库联机重定义讲解及错误处理
1.1. 关键字:联机重定义/SYNC_INTERIM_TABLE/GATHER_TABLE_STATS 1.2. 需求:数据表的清理机制需要优化 离线消息表采用delete的方式定期对过期的数据进行 ...
- 数据结构与算法之PHP排序算法(插入排序)
一.基本思想 插入排序算法是每一步将一个待排序的数据插入到前面已经排好序的有序序列中,直到所有元素插入完毕为止. 二.算法过程 1)将第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未 ...
- 前端表单验证常用的15个JS正则表达式
在表单验证中,使用正则表达式来验证正确与否是一个很频繁的操作,本文收集整理了15个常用的javaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份 ...
- SQL-61 对于employees表中,给出奇数行的first_name
题目描述 对于employees表中,给出奇数行的first_nameCREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_date` ...