├── .gitignore ├── LICENSE ├── README.md ├── config.json ├── gulpfile.js ├── index.html ├── karma.conf.js ├── karma_sourcemaps.js ├── package.json ├── src ├── abstract_factory │ ├── README.md │ ├── abstractFactory.ats │ ├── index.html │ └── runner.ats ├── adapter │ ├── README.md │ ├── adapter.ats │ ├── index.html │ └── runner.ats ├── bridge │ ├── README.md │ ├── bridge.ats │ ├── index.html │ └── runner.ats ├── builder │ ├── README.md │ ├── builder.ats │ ├── index.html │ └── runner.ats ├── command │ ├── README.md │ ├── command.ats │ ├── index.html │ └── runner.ats ├── composite │ ├── README.md │ ├── composite.ats │ ├── index.html │ └── runner.ats ├── decorator │ ├── README.md │ ├── decorator.ats │ ├── index.html │ └── runner.ats ├── facade │ ├── README.md │ ├── facade.ats │ ├── index.html │ └── runner.ats ├── factory_method │ ├── README.md │ ├── factorymethod.ats │ ├── index.html │ └── runner.ats ├── iterator │ ├── README.md │ ├── index.html │ ├── iterator.ats │ └── runner.ats ├── lang.ats ├── logger.ats ├── main.ats ├── memento │ ├── README.md │ ├── index.html │ ├── memento.ats │ └── runner.ats ├── mvc │ ├── README.md │ ├── index.html │ ├── mvc.ats │ └── runner.ats ├── observer │ ├── README.md │ ├── index.html │ ├── observer.ats │ └── runner.ats ├── prototype │ ├── README.md │ ├── index.html │ ├── prototype.ats │ └── runner.ats ├── proxy │ ├── README.md │ ├── index.html │ ├── proxy.ats │ └── runner.ats ├── publish_subscribe │ ├── README.md │ ├── index.html │ ├── pubsub.ats │ └── runner.ats ├── strategy │ ├── README.md │ ├── index.html │ ├── runner.ats │ └── strategy.ats ├── template │ ├── README.md │ ├── index.html │ ├── runner.ats │ └── template.ats └── visitor │ ├── README.md │ ├── index.html │ ├── runner.ats │ └── visitor.ats ├── wait_for_watcher.js └── webstorm_traceur.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /build 3 | .idea 4 | /out -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ziya SARIKAYA 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design Patterns and Idioms in ES6 2 | A collection of design patterns and idioms in ES6 3 | 4 | **Boilerplate forked from [angular/atscript-playground](https://github.com/angular/atscript-playground)** 5 | 6 | ### Initial setup 7 | 8 | ```bash 9 | # Clone the repo... 10 | git clone https://github.com/ziyasal/design-patterns-in-es6.git 11 | cd design-patterns-in-es6 12 | 13 | # Then, you need to install all the dependencies... 14 | npm install 15 | 16 | # If you want to be able to use global commands `karma` and `gulp`... 17 | npm install -g karma-cli gulp 18 | ``` 19 | 20 | ```bash 21 | # Do initial build, start a webserver and re-build on every file change... 22 | gulp build serve watch 23 | ``` 24 | Open a browser and see the result. 25 | 26 | Current Patterns 27 | ====================== 28 | 29 | | Pattern | Description | 30 | |:-------:| ----------- | 31 | | [abstract_factory](src/abstract_factory/abstractFactory.ats) | use a generic function with specific factories | 32 | | [adapter](src/adapter/adapter.ats) | adapt one interface to another using a whitelist | 33 | | 3-tier | data<->business logic<->presentation separation (strict relationships) | 34 | | borg | a singleton with shared-state among instances | 35 | | [bridge](src/bridge/bridge.ats) | a client-provider middleman to soften interface changes | 36 | | [builder](src/builder/builder.ats) | call many little discrete methods rather than having a huge number of constructor parameters | 37 | | catalog | general methods will call different specialized methods based on construction parameter | 38 | | chain | apply a chain of successive handlers to try and process the data | 39 | | [command](src/command/command.ats) | bundle a command and arguments to call later | 40 | | [composite](src/composite/composite.ats) | encapsulate and provide access to a number of different objects | 41 | | [decorator](src/decorator/decorator.ats) | wrap functionality with other functionality in order to affect outputs | 42 | | [facade](src/facade/facade.ats) | use one class as an API to a number of others | 43 | | [factory_method](src/factory_method/factorymethod.ats) | delegate a specialized function/method to create instances | 44 | | flyweight | transparently reuse existing instances of objects with similar/identical state | 45 | | graph_search | (graphing algorithms, not design patterns) | 46 | | mediator | an object that knows how to connect other objects and act as a proxy | 47 | | [memento](src/memento/memento.ats) | generate an opaque token that can be used to go back to a previous state | 48 | | [mvc](src/mvc/mvc.ats) | model<->view<->controller (non-strict relationships) | 49 | | [observer](src/observer/observer.ats) | provide a callback for notification of events/changes to data | 50 | | pool | preinstantiate and maintain a group of instances of the same type | 51 | | [prototype](src/prototype/prototype.ats) | use a factory and clones of a prototype for new instances (if instantiation is expensive) | 52 | | [proxy](src/proxy/proxy.ats) | an object funnels operations to something else | 53 | | [publish_subscribe](src/publish_subscribe/pubsub.ats) | a source syndicates events/data to 0+ registered listeners | 54 | | state | logic is org'd into a discrete number of potential states and the next state that can be transitioned to | 55 | | [strategy](src/strategy/strategy.ats) | selectable operations over the same data | 56 | | [template](src/template/template.ats) | an object imposes a structure but takes pluggable components | 57 | | [visitor](src/visitor/visitor.ats)| invoke a callback for all items of a collection | 58 | | chaining_method | continue callback next object method | 59 | | [iterator](src/iterator/iterator.ats) | Provide a way to access the elements of an aggregate object sequentially | 60 | 61 | 62 | ### What are all the pieces involved? 63 | 64 | #### [Traceur] 65 | Transpiles AtScript code into regular ES5 (today's JavaScript) so that it can be run in a current browser. 66 | 67 | #### [RequireJS] 68 | Traceur is configured to transpile AtScript modules into AMD syntax and we use RequireJS to load the code in the browser. 69 | 70 | #### [Assert] library 71 | When `typeAssertions: true` option is used, Traceur generates run-time type assertions such as `assert.type(x, Object)`. The assert library does the actual run-time check. Of course, you can use your own assert library. 72 | 73 | The idea with type assertions is that you only use them during the development/testing and when deploying, you use `typeAssertions: false`. 74 | 75 | #### [Karma] 76 | Test runner that runs the tests in specified browsers, every time that you change a file. 77 | 78 | #### [Gulp] 79 | Task runner to make defining and running the tasks simpler. 80 | 81 | 82 | [AtScript]: http://atscript.org 83 | [Traceur]: https://github.com/google/traceur-compiler 84 | [RequireJS]: http://requirejs.org 85 | [Assert]: https://github.com/angular/assert 86 | [Karma]: http://karma-runner.github.io/ 87 | [Gulp]: http://gulpjs.com 88 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "traceur": { 3 | "modules": "amd", 4 | "script": false, 5 | "types": true, 6 | "typeAssertions": true, 7 | "typeAssertionModule": "assert", 8 | "annotations": true, 9 | "sourceMaps": "file" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var traceur = require('gulp-traceur'); 3 | var connect = require('gulp-connect'); 4 | var rename_ = require('gulp-rename'); 5 | 6 | var TRACEUR_OPTIONS = require('./config').traceur; 7 | var PATH = { 8 | BUILD: './build/', 9 | SRC: './src/**/*.ats' 10 | }; 11 | 12 | // A wrapper around gulp-rename to support `dirnamePrefix`. 13 | function rename(obj) { 14 | return rename_(function(parsedPath) { 15 | return { 16 | extname: obj.extname || parsedPath.extname, 17 | dirname: (obj.dirnamePrefix || '') + parsedPath.dirname, 18 | basename: parsedPath.basename 19 | }; 20 | }); 21 | } 22 | 23 | 24 | // TRANSPILE AT SCRIPT 25 | gulp.task('build/src', function() { 26 | gulp.src(PATH.SRC, {base: '.'}) 27 | // Rename before Traceur, so that Traceur has the knowledge of both input and output paths. 28 | .pipe(rename({extname: '.js', dirnamePrefix: PATH.BUILD})) 29 | .pipe(traceur(TRACEUR_OPTIONS)) 30 | .pipe(gulp.dest('.')); 31 | }); 32 | 33 | gulp.task('build', ['build/src']); 34 | 35 | // WATCH FILES FOR CHANGES 36 | gulp.task('watch', function() { 37 | gulp.watch(PATH.SRC, ['build']); 38 | }); 39 | 40 | 41 | // WEB SERVER 42 | gulp.task('serve', function() { 43 | connect.server({ 44 | root: [__dirname], 45 | port: 8000, 46 | livereload: false 47 | }); 48 | }); 49 | 50 | 51 | gulp.task('default', ['serve', 'watch']); 52 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Design Patterns in AtScript 4 | 5 | 6 | 7 |

Design Patterns in AtScript

8 | 65 | 66 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Fri Mar 14 2014 15:01:19 GMT-0700 (PDT) 3 | 4 | var traceurOptions = require('./config').traceur; 5 | 6 | module.exports = function(config) { 7 | 8 | var isWebstorm = /karma-intellij/.test(process.argv[1]); 9 | var files; 10 | 11 | if (isWebstorm) { 12 | // Running within WebStorm - WebStorm takes care of transpiling. 13 | // Serve already transpiled files, including source maps. 14 | files = [ 15 | {pattern: 'build/src/**/*.js', included: false}, 16 | {pattern: 'build/test/**/*.js', included: false}, 17 | {pattern: 'build/src/**/*.map', included: false}, 18 | {pattern: 'build/test/**/*.map', included: false} 19 | ]; 20 | } else { 21 | // Running outside WebStorm (eg. from commandline). 22 | // Karma transpiles the *.ats sources with karma-traceur-preprocessor. 23 | files = [ 24 | {pattern: 'src/**/*.ats', included: false}, 25 | {pattern: 'test/**/*.ats', included: false} 26 | ]; 27 | } 28 | 29 | config.set({ 30 | frameworks: ['jasmine', 'requirejs', 'traceur', 'sourcemaps'], 31 | 32 | files: [ 33 | // The entry point that dynamically imports all the specs. 34 | {pattern: 'test/main.js', included: true}, 35 | 36 | // The runtime assertion library. 37 | {pattern: 'node_modules/rtts-assert/dist/amd/assert.js', included: false} 38 | ].concat(files), 39 | 40 | preprocessors: { 41 | '**/*.ats': ['traceur'] 42 | }, 43 | 44 | browsers: ['Chrome'], 45 | 46 | traceurPreprocessor: { 47 | options: traceurOptions, 48 | transformPath: function(path) { 49 | // Traceur preprocessor is only used when running Karma outside of WebStorm. 50 | // We change the path to `build/**` so that the paths are the same as with WebStorm. 51 | return path.replace(config.basePath, config.basePath + '/build') 52 | .replace(/\.ats$/, '.js'); 53 | } 54 | } 55 | }); 56 | 57 | config.plugins.push(require('./karma_sourcemaps')); 58 | }; 59 | -------------------------------------------------------------------------------- /karma_sourcemaps.js: -------------------------------------------------------------------------------- 1 | var SOURCE_MAP = /\.map$/; 2 | 3 | function findFile(files, path) { 4 | for (var i = 0, ii = files.length; i < ii; i++) { 5 | if (files[i].path === path) { 6 | return files[i]; 7 | } 8 | } 9 | 10 | return null; 11 | } 12 | 13 | function createSourceMapsPlugin(emitter, basePath, logger) { 14 | var log = logger.create('sourcemaps'); 15 | 16 | emitter.on('file_list_modified', function(filesPromise) { 17 | filesPromise.then(function(files) { 18 | files.served.forEach(function(file) { 19 | if (SOURCE_MAP.test(file.path)) { 20 | var sourceMap = JSON.parse(file.content); 21 | 22 | if (!sourceMap) { 23 | log.warn('Invalid source map file', file.originalPath); 24 | return; 25 | } 26 | 27 | var sourceFile = findFile(files.served, basePath + '/' + sourceMap.file); 28 | 29 | if (!sourceFile) { 30 | log.warn('Can not find source file for map', file.originalPath); 31 | return 32 | } 33 | 34 | sourceMap.sourceRoot = basePath; 35 | sourceFile.sourceMap = sourceMap; 36 | } 37 | }); 38 | }); 39 | }); 40 | } 41 | 42 | createSourceMapsPlugin.$inject = ['emitter', 'config.basePath', 'logger']; 43 | 44 | module.exports = { 45 | 'framework:sourcemaps': ['factory', createSourceMapsPlugin] 46 | }; 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "atscript-playground", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "A repo to play with AtScript.", 6 | "homepage": "https://github.com/vojtajina/atscript-playground", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/vojtajina/atscript-playground.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/vojtajina/atscript-playground/issues" 13 | }, 14 | "dependencies": { 15 | "traceur": "^0.0.72", 16 | "requirejs": "^2.1.15" 17 | }, 18 | "devDependencies": { 19 | "assert": "angular/assert#dist", 20 | "gulp": "^3.8.9", 21 | "gulp-connect": "^2.0.6", 22 | "gulp-rename": "^1.2.0", 23 | "gulp-traceur": "vojtajina/gulp-traceur#fix-sourcemaps", 24 | "karma": "^0.12.24", 25 | "karma-chrome-launcher": "^0.1.5", 26 | "karma-jasmine": "^0.2.2", 27 | "karma-requirejs": "^0.2.2", 28 | "karma-traceur-preprocessor": "^0.4.0" 29 | }, 30 | "scripts": { 31 | "test": "karma start --single-run" 32 | }, 33 | "author": "Vojta Jína ", 34 | "license": "Apache-2.0" 35 | } 36 | -------------------------------------------------------------------------------- /src/abstract_factory/README.md: -------------------------------------------------------------------------------- 1 | ## Abstract Factory Pattern ## 2 | 3 | Creates an instance of several families of classes.. -------------------------------------------------------------------------------- /src/abstract_factory/abstractFactory.ats: -------------------------------------------------------------------------------- 1 | import {Logger} from '../logger'; 2 | 3 | export class PetShop { 4 | constructor(petFactory:AbstractFactory) { 5 | this.petFactory = petFactory; 6 | this.logger = new Logger(); 7 | } 8 | 9 | showPet() { 10 | var pet = this.petFactory.getPet(); 11 | this.logger.log("We have a lovely " + pet.toString()); 12 | this.logger.log("It says " + pet.speak()); 13 | this.logger.log("We also have " + this.petFactory.getFood()); 14 | } 15 | } 16 | /* Stuff that our factory makes */ 17 | 18 | export class Animal { 19 | speak():string { 20 | throw new Error("Abstract method!"); 21 | } 22 | 23 | toString():string { 24 | throw new Error("Abstract method!"); 25 | } 26 | } 27 | 28 | export class Dog extends Animal { 29 | speak():string { 30 | return "woof"; 31 | } 32 | 33 | toString():string { 34 | return "Dog"; 35 | } 36 | } 37 | 38 | export class Cat extends Animal { 39 | speak():string { 40 | return "meow"; 41 | } 42 | 43 | toString():string { 44 | return "Cat"; 45 | } 46 | } 47 | 48 | /* Factory classes */ 49 | 50 | export class AbstractFactory { 51 | getPet():Animal { 52 | throw new Error("Abstract method!"); 53 | } 54 | 55 | getFood():string { 56 | throw new Error("Abstract method!"); 57 | } 58 | } 59 | 60 | export class DogFactory extends AbstractFactory { 61 | getPet():Animal { 62 | return new Dog(); 63 | } 64 | 65 | getFood():string { 66 | return "dog food" 67 | } 68 | } 69 | 70 | export class CatFactory extends AbstractFactory { 71 | getPet():Animal { 72 | return new Cat(); 73 | } 74 | 75 | getFood():string { 76 | return "cat food" 77 | } 78 | } -------------------------------------------------------------------------------- /src/abstract_factory/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Abstract Factory 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Abstract Factory

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/abstract_factory/runner.ats: -------------------------------------------------------------------------------- 1 | import {PetShop, CatFactory, DogFactory} from './abstractFactory'; 2 | 3 | var petShop = new PetShop(new DogFactory()); 4 | petShop.showPet(); -------------------------------------------------------------------------------- /src/adapter/README.md: -------------------------------------------------------------------------------- 1 | ## Adapter Pattern ## 2 | 3 | Convert the interface of class into another interface clients expect.Adapter lets class work together that couldn't otherwise because of incompatible interfaces. 4 | 5 | By GOF -------------------------------------------------------------------------------- /src/adapter/adapter.ats: -------------------------------------------------------------------------------- 1 | /* Generic adapter class */ 2 | 3 | export class Dog { 4 | constructor() { 5 | this.name = "Dog"; 6 | } 7 | 8 | bark(): string { 9 | return "woof!"; 10 | } 11 | } 12 | 13 | export class Cat { 14 | constructor() { 15 | this.name = "Cat" 16 | } 17 | 18 | meow(): string { 19 | return "meow!"; 20 | } 21 | } 22 | 23 | export class Human { 24 | constructor() { 25 | this.name = "Human"; 26 | } 27 | 28 | speak(): string { 29 | return "'hello'"; 30 | } 31 | } 32 | 33 | export class Car { 34 | constructor() { 35 | this.name = "Car"; 36 | } 37 | 38 | makeNoise(octaneLevel): string { 39 | return "vroom " + octaneLevel; 40 | } 41 | } 42 | 43 | export class Adapter{ 44 | constructor(obj:any, adaptedMethod:string, ...args){ 45 | this.name = obj.name; 46 | this.args = args; 47 | this.adaptedMethod = obj[adaptedMethod]; 48 | } 49 | 50 | makeNoise(){ 51 | return this.adaptedMethod(this.args); 52 | } 53 | } -------------------------------------------------------------------------------- /src/adapter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Adapter 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Adapter

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/adapter/runner.ats: -------------------------------------------------------------------------------- 1 | import {Dog, Cat, Human, Car, Adapter} from './adapter'; 2 | import { Logger } from '../logger'; 3 | 4 | var logger = new Logger(); 5 | var objects = []; 6 | var dog = new Dog(); 7 | 8 | objects.push(new Adapter(dog, 'bark')); 9 | 10 | var cat = new Cat(); 11 | objects.push(new Adapter(cat, 'meow')); 12 | 13 | var human = new Human(); 14 | objects.push(new Adapter(human, 'speak')); 15 | 16 | var car = new Car(); 17 | objects.push(new Adapter(car, 'makeNoise', 3)); 18 | 19 | objects.forEach(adapter => { 20 | logger.log("A " + adapter.name + " goes " + adapter.makeNoise()); 21 | }); -------------------------------------------------------------------------------- /src/bridge/README.md: -------------------------------------------------------------------------------- 1 | ## Bridge Pattern ## 2 | 3 | Decouple an abstraction from its implementation so that the two can vary independently. 4 | 5 | *By GOF* -------------------------------------------------------------------------------- /src/bridge/bridge.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | import { int, float } from '../lang'; 3 | 4 | //Refined Abstraction 5 | export class CircleShape { 6 | constructor(x:int, y:int, radius:float, drawingApi:DrawingAPI) { 7 | this.x = x; 8 | this.y = y; 9 | this.radius = radius; 10 | this.drawingApi = drawingApi; 11 | } 12 | 13 | //low-level i.e. Implementation specific 14 | draw() { 15 | this.drawingApi.drawCircle(this.x, this.y, this.radius); 16 | } 17 | 18 | //high-level i.e. Abstraction specific 19 | scale(pct:float) { 20 | this.radius *= pct; 21 | } 22 | } 23 | 24 | export class DrawingAPI { 25 | constructor() { 26 | this.logger = new Logger(); 27 | } 28 | 29 | drawCircle(x:int, y:int, radius:float) { 30 | throw new Error("Abstract method!"); 31 | } 32 | } 33 | 34 | //ConcreteImplementor 1/2 35 | export class DrawingAPI1 extends DrawingAPI { 36 | drawCircle(x:int, y:int, radius:float) { 37 | this.logger.log('API1.circle at ' + x + ':' + y + ' radius ' + radius); 38 | } 39 | } 40 | 41 | // ConcreteImplementor 2/2 42 | export class DrawingAPI2 extends DrawingAPI { 43 | drawCircle(x:int, y:int, radius:float) { 44 | this.logger.log('API2.circle at ' + x + ':' + y + ' radius ' + radius); 45 | } 46 | } -------------------------------------------------------------------------------- /src/bridge/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Bridge 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Bridge

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/bridge/runner.ats: -------------------------------------------------------------------------------- 1 | import {CircleShape, DrawingAPI1, DrawingAPI2} from './bridge'; 2 | 3 | var shapes = [ 4 | new CircleShape(1, 2, 3, new DrawingAPI1()), 5 | new CircleShape(5, 7, 11, new DrawingAPI2()) 6 | ]; 7 | 8 | shapes.forEach(shape=> { 9 | shape.scale(2.5); 10 | shape.draw(); 11 | }); -------------------------------------------------------------------------------- /src/builder/README.md: -------------------------------------------------------------------------------- 1 | ##Builder Pattern## 2 | 3 | Solves the problem of telescoping constructor. -------------------------------------------------------------------------------- /src/builder/builder.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | //Director 4 | export class Director { 5 | constructor() { 6 | this.builder = null; 7 | } 8 | 9 | construct(builder:Builder) { 10 | this.builder = builder; 11 | } 12 | 13 | constructBuilding() { 14 | this.builder.newBuilding(); 15 | this.builder.buildFloor(); 16 | this.builder.buildSize(); 17 | } 18 | 19 | getBuilding() { 20 | return this.builder.building; 21 | } 22 | } 23 | 24 | //Abstract Builder 25 | export class Builder { 26 | constructor() { 27 | this.building = null; 28 | } 29 | 30 | buildFloor() { 31 | throw new Error("Abstract method!"); 32 | } 33 | 34 | buildSize() { 35 | throw new Error("Abstract method!"); 36 | } 37 | 38 | newBuilding() { 39 | this.building = new Building(); 40 | } 41 | } 42 | 43 | // Concrete Builder 44 | export class HouseBuilder extends Builder { 45 | buildFloor() { 46 | this.building.floor = 'One'; 47 | } 48 | 49 | buildSize() { 50 | this.building.size = 'Big'; 51 | } 52 | } 53 | 54 | export class FlatBuilder extends Builder { 55 | buildFloor() { 56 | this.building.floor = 'More than One'; 57 | } 58 | 59 | buildSize() { 60 | this.building.size = 'Small'; 61 | } 62 | } 63 | 64 | //Product 65 | export class Building { 66 | constructor() { 67 | this.floor = null; 68 | this.size = null; 69 | } 70 | 71 | toString():string { 72 | return 'Floor: ' + this.floor + ' | Size: ' + this.size; 73 | } 74 | } -------------------------------------------------------------------------------- /src/builder/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Builder 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Builder

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/builder/runner.ats: -------------------------------------------------------------------------------- 1 | import {Director, Builder, HouseBuilder, FlatBuilder, Building} from './builder' 2 | import { Logger } from '../logger'; 3 | 4 | var logger = new Logger(); 5 | 6 | var director = new Director(); 7 | 8 | director.construct(new HouseBuilder()); 9 | director.constructBuilding(); 10 | var building1 = director.getBuilding() 11 | logger.log(building1.toString()); 12 | 13 | 14 | director.construct(new FlatBuilder()); 15 | director.constructBuilding(); 16 | var building2 = director.getBuilding() 17 | logger.log(building2.toString()); -------------------------------------------------------------------------------- /src/command/README.md: -------------------------------------------------------------------------------- 1 | ##Command Pattern## 2 | 3 | Creates objects which encapsulate actions and parameters. -------------------------------------------------------------------------------- /src/command/command.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | export class Command { 4 | constructor(receiver:Receiver) { 5 | this.logger = new Logger(); 6 | this.receiver = receiver; 7 | } 8 | 9 | execute() { 10 | throw new Error("Abstract method!"); 11 | } 12 | } 13 | 14 | export class ConcreteCommand1 extends Command { 15 | constructor(receiver:Receiver) { 16 | super(receiver); 17 | } 18 | 19 | execute() { 20 | this.logger.log("`execute` method of ConcreteCommand1 is being called!"); 21 | this.receiver.action(); 22 | } 23 | } 24 | 25 | export class ConcreteCommand2 extends Command { 26 | constructor(receiver:Receiver) { 27 | super(receiver); 28 | } 29 | 30 | execute() { 31 | this.logger.log("`execute` method of ConcreteCommand2 is being called!"); 32 | this.receiver.action(); 33 | } 34 | } 35 | 36 | export class Invoker { 37 | constructor() { 38 | this.commands = []; 39 | } 40 | 41 | storeAndExecute(cmd:Command) { 42 | this.commands.push(cmd); 43 | cmd.execute(); 44 | } 45 | } 46 | 47 | export class Receiver { 48 | constructor() { 49 | this.logger = new Logger(); 50 | } 51 | 52 | action() { 53 | this.logger.log("action is being called!"); 54 | } 55 | } -------------------------------------------------------------------------------- /src/command/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Command 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Command

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/command/runner.ats: -------------------------------------------------------------------------------- 1 | import {Receiver ,ConcreteCommand1 ,ConcreteCommand2 ,Invoker} from './command'; 2 | 3 | var receiver = new Receiver(); 4 | var command1 = new ConcreteCommand1(receiver); 5 | var command2 = new ConcreteCommand2(receiver); 6 | var invoker = new Invoker(); 7 | 8 | invoker.storeAndExecute(command1); 9 | invoker.storeAndExecute(command2); -------------------------------------------------------------------------------- /src/composite/README.md: -------------------------------------------------------------------------------- 1 | ##Composite Pattern## 2 | 3 | Composite pattern is used where we need to treat a group of objects in similar way as a single object. -------------------------------------------------------------------------------- /src/composite/composite.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | import { int, float } from '../lang'; 3 | 4 | 5 | export class Employee { 6 | constructor(name:string, dept:string, sal:int) { 7 | this.subordinates = []; 8 | this.name = name; 9 | this.dept = dept; 10 | this.sal = sal; 11 | } 12 | add(e:Employee) { 13 | this.subordinates.push(e); 14 | } 15 | remove(e:Employee) { 16 | 17 | var index = this.subordinates.indexOf(e); 18 | if (index > -1) { 19 | this.subordinates.splice(index, 1); 20 | } 21 | } 22 | 23 | get Subordinates() { 24 | return this.subordinates; 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/composite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Composite 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Composite

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/composite/runner.ats: -------------------------------------------------------------------------------- 1 | import {Employee} from './composite'; 2 | import { Logger } from '../logger'; 3 | 4 | var logger = new Logger(); 5 | var ceo = new Employee("John", "CEO", 30000); 6 | var headSales = new Employee("Robert", "Head Sales", 20000); 7 | 8 | var headMarketing = new Employee("Michel", "Head Marketing", 20000); 9 | 10 | var clerk1 = new Employee("Laura", "Marketing", 10000); 11 | var clerk2 = new Employee("Bob", "Marketing", 10000); 12 | 13 | var salesExecutive1 = new Employee("Richard", "Sales", 10000); 14 | var salesExecutive2 = new Employee("Rob", "Sales", 10000); 15 | 16 | 17 | ceo.add(headSales); 18 | ceo.add(headMarketing); 19 | headSales.add(salesExecutive1); 20 | headSales.add(salesExecutive2); 21 | 22 | headMarketing.add(clerk1); 23 | headMarketing.add(clerk2); 24 | 25 | 26 | logger.log(JSON.stringify(ceo)); 27 | logger.log(JSON.stringify(headSales)); 28 | 29 | //Refactor code. For loop 30 | 31 | ceo.subordinates.forEach(_ceo=> { 32 | logger.log(JSON.stringify(_ceo)); 33 | }); 34 | 35 | -------------------------------------------------------------------------------- /src/decorator/README.md: -------------------------------------------------------------------------------- 1 | ##Decorator Pattern## 2 | 3 | Decorator pattern allows a user to add new functionality to an existing object without altering its structure. 4 | This type of design pattern comes under structural pattern as this pattern acts as a wrapper to existing class. -------------------------------------------------------------------------------- /src/decorator/decorator.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | //Defined Interface 4 | export class Shape { 5 | constructor() { 6 | this.logger = new Logger(); 7 | } 8 | 9 | draw() { 10 | throw new Error("Interface!"); 11 | } 12 | } 13 | //Concrete Implementor 1/2 14 | export class Circle extends Shape { 15 | 16 | draw() { 17 | this.logger.log("Shape:Circle"); 18 | } 19 | } 20 | //Concrete Implementor 2/2 21 | export class Rectangle extends Shape { 22 | 23 | draw() { 24 | this.logger.log("Shape:Rectangle"); 25 | } 26 | } 27 | //Abstract class 28 | export class ShapeDecorator extends Shape { 29 | constructor(_decoratedShape:Shape) { 30 | this.decoratedShape = _decoratedShape; 31 | this.logger = new Logger(); 32 | } 33 | 34 | draw() { 35 | this.decoratedShape.draw(); 36 | } 37 | } 38 | //Concrete implementor of abstract class 39 | export class RedShapeDecorator extends ShapeDecorator { 40 | constructor(_decoratedShape:Shape) { 41 | this.redDecoratedShape = _decoratedShape; 42 | super(this.redDecoratedShape); 43 | } 44 | 45 | setRedBorder(redDecoratedShape:Shape) { 46 | this.logger.log("Border color: Red."); 47 | } 48 | 49 | draw() { 50 | this.redDecoratedShape.draw(); 51 | this.setRedBorder(this.redDecoratedShape); 52 | } 53 | } -------------------------------------------------------------------------------- /src/decorator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Decorator 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Decorator

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/decorator/runner.ats: -------------------------------------------------------------------------------- 1 | import {Circle,Rectangle,RedShapeDecorator} from './decorator'; 2 | 3 | var circle = new Circle(); 4 | var redCircle = new RedShapeDecorator(new Circle()); 5 | var redRectangle = new RedShapeDecorator(new Rectangle()); 6 | 7 | circle.draw(); 8 | redCircle.draw(); 9 | redRectangle.draw(); 10 | -------------------------------------------------------------------------------- /src/facade/README.md: -------------------------------------------------------------------------------- 1 | ##Facade Pattern## 2 | 3 | A facade is an object that provides a simplified interface to a larger body of code. -------------------------------------------------------------------------------- /src/facade/facade.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | export class AbstractFacade { 4 | constructor() { 5 | this.logger = new Logger(); 6 | } 7 | } 8 | export class MonitorFacade extends AbstractFacade{ 9 | setMonitor() { 10 | this.logger.log("You have Monitor."); 11 | } 12 | } 13 | 14 | export class KeyboardFacade extends AbstractFacade{ 15 | setKeyboard() { 16 | this.logger.log("You have keyboard."); 17 | } 18 | } 19 | 20 | export class MouseFacade extends AbstractFacade{ 21 | setMouse() { 22 | this.logger.log("You have mouse."); 23 | } 24 | } 25 | export class LaptopFacade extends AbstractFacade{ 26 | setLaptop() { 27 | this.logger.log("You have laptop."); 28 | } 29 | } 30 | export class ComputerFacade extends AbstractFacade{ 31 | constructor() { 32 | super(); 33 | this.monitor = new MonitorFacade(); 34 | this.keyboard = new KeyboardFacade(); 35 | this.mouse = new MouseFacade(); 36 | this.laptop = new LaptopFacade(); 37 | } 38 | buildComputer() { 39 | this.monitor.setMonitor(); 40 | this.keyboard.setKeyboard(); 41 | this.mouse.setMouse(); 42 | this.laptop.setLaptop(); 43 | this.logger.log("You have built a computer."); 44 | } 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/facade/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Facade 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Facade

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/facade/runner.ats: -------------------------------------------------------------------------------- 1 | import {ComputerFacade} from './facade'; 2 | 3 | var computerFacade = new ComputerFacade(); 4 | computerFacade.buildComputer(); -------------------------------------------------------------------------------- /src/factory_method/README.md: -------------------------------------------------------------------------------- 1 | ##Factory-Method Pattern## 2 | 3 | In Factory-Method pattern, object is created without exposing the creation logic to the client and refer to newly created object using a common interface. -------------------------------------------------------------------------------- /src/factory_method/factorymethod.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | //Defined Interface 4 | export class Shape{ 5 | constructor(){ 6 | this.logger = new Logger(); 7 | } 8 | 9 | draw(){ 10 | throw new Error("Interface!"); 11 | } 12 | } 13 | //Concrete implementor 1/3 14 | export class Square extends Shape { 15 | draw() { 16 | this.logger.log("Square is created!"); 17 | } 18 | } 19 | //Concrete implementor 2/3} 20 | export class Rectangle extends Shape{ 21 | draw(){ 22 | this.logger.log("Rectangle is created!"); 23 | } 24 | } 25 | //Concrete implementor 3/3 26 | export class Circle extends Shape{ 27 | draw(){ 28 | this.logger.log("Circle is created!") 29 | } 30 | } 31 | export class ShapeFactory{ 32 | //use getShape method to get object of type shape 33 | getShape(shapeType:string):Shape{ 34 | if(shapeType == null) 35 | return null; 36 | else if(shapeType === 'CIRCLE') 37 | return new Circle(); 38 | else if(shapeType === 'RECTANGLE') 39 | return new Rectangle(); 40 | else if(shapeType === 'SQUARE') 41 | return new Square(); 42 | else 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/factory_method/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Factory-Method 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Factory-Method

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/factory_method/runner.ats: -------------------------------------------------------------------------------- 1 | import {ShapeFactory,Circle,Rectangle,Square} from './factorymethod'; 2 | 3 | var shapeFactory = new ShapeFactory(); 4 | 5 | //get an object of Circle and call its draw method. 6 | var circleShape = shapeFactory.getShape("CIRCLE"); 7 | 8 | //call draw method of Circle 9 | circleShape.draw(); 10 | 11 | //get an object of Rectangle and call its draw method. 12 | var rectangleShape = shapeFactory.getShape("RECTANGLE"); 13 | 14 | //call draw method of Rectangle 15 | rectangleShape.draw(); 16 | 17 | //get an object of Square and call its draw method. 18 | var squareShape = shapeFactory.getShape("SQUARE"); 19 | 20 | //call draw method of circle 21 | squareShape.draw(); -------------------------------------------------------------------------------- /src/iterator/README.md: -------------------------------------------------------------------------------- 1 | ##Iterator Pattern## 2 | 3 | Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. -------------------------------------------------------------------------------- /src/iterator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Iterator 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Iterator

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/iterator/iterator.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | export class Aggregate { 4 | constructor() { 5 | this.items = []; 6 | } 7 | 8 | get Count() { 9 | return this.items.length; 10 | } 11 | 12 | } 13 | //Abstract class 14 | export class Iterator { 15 | firstObject():any { 16 | throw new Error("Abstract method!"); 17 | } 18 | 19 | nextObject():any { 20 | throw new Error("Abstract method!"); 21 | } 22 | 23 | currentObject():any { 24 | throw new Error("Abstract method!"); 25 | } 26 | 27 | isDone():boolean { 28 | throw new Error("Abstract method!"); 29 | } 30 | } 31 | //Concrete of Iterator 32 | export class ConcreteIterator extends Iterator { 33 | 34 | constructor(aggregate:Aggregate) { 35 | this._aggregate = aggregate; 36 | this._items = this._aggregate.items; 37 | this.index = 0; 38 | } 39 | 40 | firstObject():any { 41 | return this._items[0]; 42 | } 43 | 44 | nextObject():any { 45 | var retVal = null; 46 | if (this.index < (this._aggregate.Count - 1)) 47 | retVal = this._items[++this.index]; 48 | else 49 | retVal = "There is no more item in the list!"; 50 | return retVal; 51 | } 52 | 53 | isDone():boolean { 54 | return this.index >= (this._aggregate.Count - 1); 55 | } 56 | 57 | currentObject() { 58 | return this._items[this.index]; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/iterator/runner.ats: -------------------------------------------------------------------------------- 1 | import {ConcreteIterator,Aggregate} from './iterator'; 2 | import { Logger } from '../logger'; 3 | var logger = new Logger(); 4 | var aggregate = new Aggregate(); 5 | aggregate.items[0] = "ITEM 1"; 6 | aggregate.items[1] = "ITEM 2"; 7 | aggregate.items[2] = "ITEM 3"; 8 | aggregate.items[3] = "ITEM 4"; 9 | 10 | var iterator = new ConcreteIterator(aggregate); 11 | 12 | logger.log("Next object: " + iterator.nextObject()); 13 | logger.log("Current object: " + iterator.currentObject()); 14 | logger.log("Next object: " + iterator.nextObject()); 15 | logger.log("First object: " + iterator.firstObject()); 16 | logger.log("Next object: " + iterator.nextObject()); 17 | if (iterator.isDone()) 18 | logger.log("Iterator is done!"); 19 | else { 20 | logger.log("Not yet!"); 21 | } 22 | logger.log("Next object: " + iterator.nextObject()); 23 | -------------------------------------------------------------------------------- /src/lang.ats: -------------------------------------------------------------------------------- 1 | export function int() { 2 | }; 3 | int.assert = function (value) { 4 | return value == null || typeof value == 'number' && value === Math.floor(value); 5 | }; 6 | 7 | export function float() { 8 | }; 9 | float.assert = function (value) { 10 | return value == null || typeof value == 'number'; 11 | }; -------------------------------------------------------------------------------- /src/logger.ats: -------------------------------------------------------------------------------- 1 | export class Logger { 2 | constructor() { 3 | this.container = document.getElementById("logContainer"); 4 | } 5 | log(message: string) { 6 | var li = document.createElement("li"); 7 | li.appendChild(document.createTextNode(message)); 8 | this.container.appendChild(li); 9 | } 10 | } -------------------------------------------------------------------------------- /src/main.ats: -------------------------------------------------------------------------------- 1 | export class Main { 2 | 3 | } -------------------------------------------------------------------------------- /src/memento/README.md: -------------------------------------------------------------------------------- 1 | ##Memento Pattern## 2 | 3 | Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. -------------------------------------------------------------------------------- /src/memento/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Memento 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Memento

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/memento/memento.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | import { int, float } from '../lang'; 3 | 4 | export class Originator { 5 | constructor() { 6 | this.logger = new Logger(); 7 | } 8 | 9 | set State(_state:string) { 10 | this.state = _state; 11 | } 12 | 13 | get State():string { 14 | return this.state; 15 | } 16 | 17 | set stateFromMemento(memento:Memento) { 18 | this.state = memento.MementoState; 19 | } 20 | 21 | get stateToBeSavedMemento():Memento { 22 | return (new Memento(this.state)); 23 | } 24 | 25 | } 26 | export class Memento { 27 | constructor(_state:string) { 28 | this.mementoState = _state; 29 | } 30 | 31 | get MementoState():string { 32 | return this.mementoState; 33 | } 34 | 35 | } 36 | export class CareTaker { 37 | constructor() { 38 | this.mementoList = []; 39 | } 40 | 41 | addStateToMementoList(_state:Memento) { 42 | this.mementoList.push(_state); 43 | } 44 | 45 | getStateFromMementoList(index:int):Memento { 46 | return this.mementoList[index]; 47 | } 48 | } -------------------------------------------------------------------------------- /src/memento/runner.ats: -------------------------------------------------------------------------------- 1 | import {Originator,CareTaker} from './memento'; 2 | import { Logger } from '../logger'; 3 | 4 | var originator = new Originator(); 5 | var careTaker = new CareTaker(); 6 | var logger = new Logger(); 7 | originator.State = "State #1"; 8 | originator.State = "State #2"; 9 | careTaker.addStateToMementoList(originator.stateToBeSavedMemento); 10 | 11 | originator.State = "State #3"; 12 | careTaker.addStateToMementoList(originator.stateToBeSavedMemento); 13 | originator.State = "State #4"; 14 | logger.log("Current state is: " + originator.State); 15 | originator.stateFromMemento = careTaker.getStateFromMementoList(0); 16 | logger.log("First saved state is: " + originator.State); 17 | originator.stateFromMemento = careTaker.getStateFromMementoList(1); 18 | logger.log("Second saved state is: " + originator.State); 19 | 20 | -------------------------------------------------------------------------------- /src/mvc/README.md: -------------------------------------------------------------------------------- 1 | ##MVC Pattern## 2 | 3 | It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user. -------------------------------------------------------------------------------- /src/mvc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | MVC 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

MVC

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/mvc/mvc.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | export class Student { 4 | get Number():string { 5 | return this.rollNo; 6 | } 7 | 8 | get Name():string { 9 | return this.studentName; 10 | } 11 | 12 | set Name(name:string) { 13 | this.studentName = name; 14 | } 15 | 16 | set Number(number:string) { 17 | this.rollNo = number; 18 | } 19 | } 20 | export class StudentView { 21 | constructor() { 22 | this.logger = new Logger(); 23 | } 24 | 25 | printStudentDetails(name:string, number:string) { 26 | this.logger.log("Student:"); 27 | this.logger.log("Name:" + name); 28 | this.logger.log("Roll no:" + number); 29 | } 30 | } 31 | export class StudentController { 32 | constructor(model:Student, view:StudentView) { 33 | this.studentModel = model; 34 | this.studentView = view; 35 | } 36 | 37 | get StudentName():string { 38 | return this.studentModel.Name; 39 | } 40 | 41 | get StudentNumber():string { 42 | return this.studentModel.Number; 43 | } 44 | 45 | set StudentName(name:string) { 46 | this.studentModel.Name = name; 47 | } 48 | 49 | set StudentNumber(number:string) { 50 | this.studentModel.Number = number; 51 | } 52 | 53 | updateView() { 54 | this.studentView.printStudentDetails(this.studentModel.Name, this.studentModel.Number); 55 | } 56 | 57 | } 58 | export class DBManager{ 59 | retriveStudentFromDatabase():Student{ 60 | var student = new Student(); 61 | student.Name = "Robert"; 62 | student.Number = "10"; 63 | return student; 64 | } 65 | } -------------------------------------------------------------------------------- /src/mvc/runner.ats: -------------------------------------------------------------------------------- 1 | import {Student,StudentController,StudentView,DBManager} from './mvc' 2 | 3 | //fetch student record based on his roll no from the database 4 | var db = new DBManager(); 5 | var model = db.retriveStudentFromDatabase(); 6 | 7 | //Create a view : to write student details on console 8 | var view = new StudentView(); 9 | 10 | var controller = new StudentController(model, view); 11 | controller.updateView(); 12 | 13 | //update model data 14 | controller.StudentName = "John"; 15 | controller.StudentNumber = "15"; 16 | 17 | controller.updateView(); -------------------------------------------------------------------------------- /src/observer/README.md: -------------------------------------------------------------------------------- 1 | ##Observer Pattern## 2 | 3 | Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. -------------------------------------------------------------------------------- /src/observer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Observer 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Observer

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/observer/observer.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | import { int } from '../lang'; 3 | 4 | export class Subject { 5 | constructor() { 6 | this.observers = []; 7 | this.logger = new Logger(); 8 | } 9 | 10 | register(observer:Observer) { 11 | this.logger.log(observer.toString() + " is pushed!"); 12 | this.observers.push(observer); 13 | } 14 | 15 | unregister(observer:Observer) { 16 | var n:int = this.observers.indexOf(observer); 17 | this.logger.log(observer.toString() + " is removed"); 18 | this.observers.splice(n, 1); 19 | } 20 | 21 | notify() { 22 | this.logger.log("notify all the observers"); 23 | 24 | for (var i = 0, max = this.observers.length; i < max; i += 1) { 25 | this.observers[i].notify(); 26 | } 27 | } 28 | } 29 | 30 | export class ConcreteSubject extends Subject { 31 | get SubjectState():int { 32 | return this.subjectState; 33 | } 34 | 35 | set SubjectState(subjectState:int) { 36 | this.subjectState = subjectState; 37 | } 38 | } 39 | 40 | 41 | export class Observer { 42 | constructor() { 43 | this.logger = new Logger(); 44 | } 45 | 46 | notify() { 47 | throw new Error("Abstract Method!"); 48 | } 49 | 50 | toString():string { 51 | 52 | } 53 | } 54 | 55 | export class ConcreteObserver extends Observer { 56 | constructor(subject:ConcreteSubject, name:string) { 57 | super(); 58 | this.logger.log("ConcreteObserver " + name + " is created!"); 59 | this.subject = subject; 60 | this.name = name; 61 | } 62 | 63 | notify() { 64 | this.logger.log("ConcreteObserver's notify method"); 65 | this.logger.log(this.name, this.state); 66 | this.state = this.subject.SubjectState; 67 | } 68 | 69 | get Subject():ConcreteSubject { 70 | return this.subject; 71 | } 72 | 73 | set Subject(subject:ConcreteSubject) { 74 | this.subject = subject; 75 | } 76 | 77 | toString():string { 78 | return this.name; 79 | } 80 | } -------------------------------------------------------------------------------- /src/observer/runner.ats: -------------------------------------------------------------------------------- 1 | import {ConcreteSubject ,ConcreteObserver} from './observer'; 2 | 3 | 4 | var sub = new ConcreteSubject(); 5 | 6 | sub.register(new ConcreteObserver(sub, "Aaron")); 7 | sub.register(new ConcreteObserver(sub, "Swartz")); 8 | sub.register(new ConcreteObserver(sub, "Reddit")); 9 | 10 | sub.SubjectState = 123; 11 | sub.notify(); -------------------------------------------------------------------------------- /src/prototype/README.md: -------------------------------------------------------------------------------- 1 | ##Prototype Pattern## 2 | 3 | In the prototype pattern, a new object is created by cloning an existing object. -------------------------------------------------------------------------------- /src/prototype/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Prototype 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Prototype

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/prototype/prototype.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | import { int, float } from '../lang'; 3 | 4 | export class Prototype { 5 | 6 | constructor(){ 7 | 8 | } 9 | 10 | doClone():Prototype { 11 | 12 | throw new Error("Abstract method!"); 13 | } 14 | 15 | } 16 | 17 | export class Person extends Prototype { 18 | 19 | constructor(surname:string) { 20 | this.logger = new Logger(); 21 | 22 | this.surname = surname; 23 | } 24 | 25 | doClone():Prototype { 26 | 27 | return new Person(this.surname); 28 | } 29 | 30 | toString():string{ 31 | 32 | return this.logger.log("This person is named " + this.surname); 33 | } 34 | } 35 | 36 | 37 | export class Dog extends Prototype { 38 | 39 | constructor(sound:string) { 40 | this.logger = new Logger(); 41 | 42 | this.sound = sound; 43 | } 44 | 45 | doClone():Prototype { 46 | 47 | return new Dog(this.sound); 48 | } 49 | 50 | toString():string { 51 | 52 | return this.logger.log("This dog says " + this.sound); 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/prototype/runner.ats: -------------------------------------------------------------------------------- 1 | import {Prototype, Person, Dog} from './prototype'; 2 | 3 | 4 | var person1 = new Person("Fred"); 5 | 6 | var person2 = person1.doClone(); 7 | person1.toString(); 8 | person2.toString(); 9 | 10 | 11 | var dog1 = new Dog("Wooof!"); 12 | dog1.toString(); 13 | 14 | var dog2 = dog1.doClone(); 15 | dog2.toString(); -------------------------------------------------------------------------------- /src/proxy/README.md: -------------------------------------------------------------------------------- 1 | ##Proxy Pattern## 2 | 3 | Provide a surrogate or placeholder for another object to control access to it. -------------------------------------------------------------------------------- /src/proxy/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Proxy 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Proxy

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/proxy/proxy.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | //Real Class 4 | export class Driving { 5 | constructor() { 6 | this.logger = new Logger(); 7 | } 8 | 9 | startEngine() { 10 | this.logger.log("Engine is started."); 11 | } 12 | 13 | hitGas() { 14 | this.logger.log("Car is accelerated."); 15 | } 16 | 17 | hitBrake() { 18 | this.logger.log("Car is stopped."); 19 | } 20 | 21 | parkCark() { 22 | this.logger.log("Car is parked."); 23 | } 24 | 25 | stopEngine() { 26 | this.logger.log("Engine is stopped."); 27 | } 28 | } 29 | //Proxy Class 30 | export class ProxyDriving extends Driving { 31 | constructor() { 32 | this._driving = new Driving(); 33 | } 34 | 35 | startEngine() { 36 | this._driving.startEngine(); 37 | } 38 | 39 | hitGas() { 40 | this._driving.hitGas(); 41 | } 42 | 43 | hitBrake() { 44 | this._driving.hitBrake(); 45 | } 46 | 47 | parkCark() { 48 | this._driving.parkCark(); 49 | } 50 | 51 | stopEngine() { 52 | this._driving.stopEngine(); 53 | } 54 | } -------------------------------------------------------------------------------- /src/proxy/runner.ats: -------------------------------------------------------------------------------- 1 | import {ProxyDriving} from './proxy'; 2 | 3 | var proxy = new ProxyDriving(); 4 | proxy.startEngine(); 5 | proxy.hitGas(); 6 | proxy.hitBrake(); 7 | proxy.parkCark(); 8 | proxy.stopEngine(); 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/publish_subscribe/README.md: -------------------------------------------------------------------------------- 1 | ##Publish Subscribe## -------------------------------------------------------------------------------- /src/publish_subscribe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Publish Subscribe 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Publish Subscribe

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/publish_subscribe/pubsub.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | export class Provider { 4 | constructor() { 5 | this.msgQueue = [] 6 | this.subscribers = {} 7 | } 8 | 9 | notify(msg:string) { 10 | this.msgQueue.push(msg) 11 | } 12 | 13 | subscribe(msg:string, subscriber:Subscriber) { 14 | if (!(msg in this.subscribers)) { 15 | this.subscribers[msg] = []; 16 | } 17 | 18 | this.subscribers[msg].push(subscriber); 19 | } 20 | 21 | unsubscribe(msg:string, subscriber:Subscriber) { 22 | var subscribers = this.subscribers[msg]; 23 | var index = subscribers.indexOf(subscriber); 24 | if (index > -1) { 25 | subscribers.splice(index, 1); 26 | } 27 | } 28 | 29 | update() { 30 | var _that = this; 31 | this.msgQueue.forEach(msg=> { 32 | if (msg in this.subscribers) { 33 | _that.subscribers[msg].forEach(sub=> { 34 | sub.run(msg) 35 | }); 36 | } 37 | }); 38 | 39 | this.msgQueue = [] 40 | } 41 | } 42 | 43 | export class Publisher { 44 | constructor(msgCenter:Provider) { 45 | this.provider = msgCenter; 46 | } 47 | 48 | publish(msg:string) { 49 | this.provider.notify(msg) 50 | } 51 | } 52 | 53 | export class Subscriber { 54 | constructor(name:string, msgCenter:Provider) { 55 | this.name = name; 56 | this.provider = msgCenter; 57 | this.logger = new Logger(); 58 | } 59 | 60 | subscribe(msg:string) { 61 | this.provider.subscribe(msg, this); 62 | } 63 | 64 | run(msg:string) { 65 | this.logger.log(this.name + " & " + msg); 66 | } 67 | } -------------------------------------------------------------------------------- /src/publish_subscribe/runner.ats: -------------------------------------------------------------------------------- 1 | import {Provider ,Subscriber,Publisher} from './pubsub'; 2 | 3 | 4 | var messageCenter = new Provider(); 5 | 6 | var fftv = new Publisher(messageCenter); 7 | 8 | var aaron = new Subscriber("aaron", messageCenter); 9 | aaron.subscribe("reddit"); 10 | 11 | var aamir = new Subscriber("aamir", messageCenter); 12 | aamir.subscribe("movie"); 13 | 14 | var gee = new Subscriber("turing", messageCenter); 15 | gee.subscribe("science"); 16 | 17 | fftv.publish("reddit"); 18 | fftv.publish("science"); 19 | fftv.publish("ads"); 20 | fftv.publish("movie"); 21 | fftv.publish("reddit"); 22 | fftv.publish("reddit"); 23 | fftv.publish("science"); 24 | fftv.publish("blank"); 25 | 26 | messageCenter.update(); -------------------------------------------------------------------------------- /src/strategy/README.md: -------------------------------------------------------------------------------- 1 | ##Strategy Pattern## 2 | 3 | Creates objects which represent various strategies and a context object whose behavior varies as per its strategy object. -------------------------------------------------------------------------------- /src/strategy/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Strategy 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Strategy

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/strategy/runner.ats: -------------------------------------------------------------------------------- 1 | import {Strategy, Context, OperationAdd,OperationSubstract,OperationMultiply} from './strategy'; 2 | 3 | 4 | 5 | var contextAdd = new Context(new OperationAdd()); 6 | var contextSub = new Context(new OperationSubstract()); 7 | var contextMultiply = new Context(new OperationMultiply()); 8 | 9 | contextAdd.executeStrategy(1,10); 10 | contextSub.executeStrategy(12,5); 11 | contextMultiply.executeStrategy(5,10); 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/strategy/strategy.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | import { int, float } from '../lang'; 3 | 4 | 5 | export class Strategy { 6 | constructor() { 7 | this.logger = new Logger(); 8 | 9 | } 10 | 11 | doOperation(num1:int, num2:int) { 12 | throw new Error("Abstract method!"); 13 | } 14 | } 15 | export class Context { 16 | constructor(strategy:Strategy) { 17 | this.strategy = strategy; 18 | } 19 | 20 | executeStrategy(num1:int, num2:int) { 21 | return this.strategy.doOperation(num1, num2); 22 | } 23 | 24 | } 25 | export class OperationAdd extends Strategy { 26 | doOperation(num1:int, num2:int) { 27 | this.logger.log("add of operation" + ':' + (num1 + num2).toString()); 28 | 29 | } 30 | } 31 | 32 | export class OperationSubstract extends Strategy { 33 | doOperation(num1:int, num2:int) { 34 | this.logger.log('sub of operation' + ':' + (num1 - num2).toString()); 35 | } 36 | } 37 | 38 | export class OperationMultiply extends Strategy { 39 | doOperation(num1:int, num2:int) { 40 | this.logger.log('multiply of operation' + ':' + (num1 * num2).toString()); 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/template/README.md: -------------------------------------------------------------------------------- 1 | ##Template Pattern## 2 | 3 | Template Method is a behavioral design pattern and it’s used to create a method stub and deferring some of the steps of implementation to the subclasses. -------------------------------------------------------------------------------- /src/template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Template 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Template

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/template/runner.ats: -------------------------------------------------------------------------------- 1 | import {HouseTemplate,WoodenHouse,GlassHouse} from './template'; 2 | 3 | var glassHouse = new GlassHouse(); 4 | 5 | glassHouse.buildHouse(); 6 | 7 | var woodenHouse = new WoodenHouse(); 8 | woodenHouse.buildHouse(); 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/template/template.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | 3 | export class HouseTemplate { 4 | constructor() { 5 | this.logger = new Logger(); 6 | } 7 | 8 | //Template method, final so subclasses can't override 9 | buildHouse() { 10 | this.buildFoundation(); 11 | this.buildPillars(); 12 | this.buildWalls(); 13 | this.buildWindows(); 14 | this.logger.log("House is built."); 15 | this.logger.log("***************"); 16 | 17 | } 18 | 19 | //Always same for all kinds of concrete classes so it is implemented in base. 20 | buildFoundation() { 21 | this.logger.log("Building foundation with cement,iron rods and sand"); 22 | } 23 | 24 | //Always same for all kinds of concrete classes so it is implemented in base. 25 | buildWindows() { 26 | this.logger.log("Building glass windows"); 27 | } 28 | 29 | //Abstract method which is to be implemented in concrete classes 30 | buildPillars() { 31 | throw new Error("Abstract Method!"); 32 | } 33 | 34 | //Abstract method which is to be implemented in concrete classes 35 | buildWalls() { 36 | throw new Error("Abstract Method!"); 37 | } 38 | 39 | 40 | } 41 | //Concrete implementor 1/2 42 | export class WoodenHouse extends HouseTemplate { 43 | buildWalls() { 44 | this.logger.log("Building wooden walls."); 45 | } 46 | 47 | buildPillars() { 48 | this.logger.log("Building pillars with wooden coating."); 49 | } 50 | } 51 | //Concrete implementor 2/2 52 | export class GlassHouse extends HouseTemplate { 53 | buildWalls() { 54 | this.logger.log("Building glass walls."); 55 | } 56 | 57 | buildPillars() { 58 | this.logger.log("Building pillars with glass coating."); 59 | } 60 | } -------------------------------------------------------------------------------- /src/visitor/README.md: -------------------------------------------------------------------------------- 1 | ##Visitor Pattern## 2 | 3 | A visitor class which changes the executing algorithm of an element class. 4 | -------------------------------------------------------------------------------- /src/visitor/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Visitor 4 | 5 | 6 | 7 | Home 8 |
9 | 10 |

Visitor

11 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/visitor/runner.ats: -------------------------------------------------------------------------------- 1 | import { 2 | ComputerPart, 3 | Computer, 4 | ComputerPartVisitor, 5 | ComputerPartDisplayVisitor, 6 | Mouse, 7 | Keyboard, 8 | Monitor 9 | } from './visitor'; 10 | 11 | 12 | var computerPart = new Computer(); 13 | computerPart.accept(new ComputerPartDisplayVisitor()); 14 | -------------------------------------------------------------------------------- /src/visitor/visitor.ats: -------------------------------------------------------------------------------- 1 | import { Logger } from '../logger'; 2 | import { int, float } from '../lang'; 3 | 4 | 5 | export class ComputerPart { 6 | accept(computerPartVisitor:ComputerPartVisitor) { 7 | throw new Error("Abstract Method!"); 8 | } 9 | } 10 | 11 | export class Keyboard extends ComputerPart { 12 | accept(computerPartVisitor:ComputerPartVisitor) { 13 | computerPartVisitor.visitKeyboard(this); 14 | } 15 | } 16 | 17 | export class Monitor extends ComputerPart { 18 | accept(computerPartVisitor:ComputerPartVisitor) { 19 | computerPartVisitor.visitMonitor(this); 20 | } 21 | } 22 | 23 | export class Mouse extends ComputerPart { 24 | accept(computerPartVisitor:ComputerPartVisitor) { 25 | computerPartVisitor.visitMouse(this); 26 | } 27 | } 28 | 29 | 30 | export class Computer extends ComputerPart { 31 | constructor() { 32 | this.parts = [new Mouse, new Keyboard(), new Monitor()]; 33 | } 34 | 35 | accept(computerPartVisitor:ComputerPartVisitor) { 36 | this.parts.forEach(part=> { 37 | part.accept(computerPartVisitor); 38 | }); 39 | computerPartVisitor.visitComputer(this); 40 | } 41 | } 42 | 43 | export class ComputerPartVisitor { 44 | constructor() { 45 | this.logger = new Logger(); 46 | } 47 | 48 | visitComputer(computer:Computer) { 49 | throw new Error("Abstract Method!"); 50 | } 51 | 52 | visitMouse(mouse:Mouse) { 53 | throw new Error("Abstract Method!"); 54 | } 55 | 56 | visitKeyboard(keyboard:Keyboard) { 57 | throw new Error("Abstract Method!"); 58 | } 59 | 60 | visitMonitor(monitor:Monitor) { 61 | throw new Error("Abstract Method!"); 62 | } 63 | } 64 | 65 | export class ComputerPartDisplayVisitor extends ComputerPartVisitor { 66 | visitComputer(computer:Computer) { 67 | this.logger.log("Displaying Computer."); 68 | } 69 | 70 | visitMouse(mouse:Mouse) { 71 | this.logger.log("Displaying Mouse."); 72 | } 73 | 74 | visitKeyboard(keyboard:Keyboard) { 75 | this.logger.log("Displaying Keyboard."); 76 | } 77 | 78 | visitMonitor(monitor:Monitor) { 79 | this.logger.log("Displaying Monitor."); 80 | } 81 | } -------------------------------------------------------------------------------- /wait_for_watcher.js: -------------------------------------------------------------------------------- 1 | // Wait for any outstanding Traceur watchers. 2 | // Hack to work-around https://youtrack.jetbrains.com/issue/WEB-14104 3 | 4 | // How it works? 5 | // WebStorm Traceur watcher writes LOCK_FILE when running and delete LOCK_FILE once all watchers are finished. 6 | // WebStorm Karma configuration waits for this process to finish (i.e. till the LOCK_FILE is removed). 7 | 8 | var fs = require('fs'); 9 | var LOCK_FILE = '.atscriptwatcher'; 10 | var START_DELAY = 500; 11 | 12 | setTimeout(function() { 13 | if (!fs.existsSync(LOCK_FILE)) { 14 | // Watcher was not running. 15 | process.exit(0); 16 | } 17 | 18 | fs.watch(LOCK_FILE, function() { 19 | if (!fs.existsSync(LOCK_FILE)) { 20 | // All watchers have finished. 21 | process.exit(0); 22 | } 23 | }); 24 | }, START_DELAY); 25 | 26 | 27 | -------------------------------------------------------------------------------- /webstorm_traceur.js: -------------------------------------------------------------------------------- 1 | var inputFilename = process.argv[2]; 2 | var outputFilename = process.argv[3] || inputFilename.replace(/\.ats$/, '.js'); 3 | 4 | var path = require('path'); 5 | var sourceRoot = path.relative(path.dirname(outputFilename), ''); 6 | 7 | var TraceurNodeCompiler = require('traceur/src/node/NodeCompiler').NodeCompiler; 8 | var options = require('./config.json').traceur; 9 | var compiler = new TraceurNodeCompiler(options); 10 | 11 | 12 | // Increment the lock to delay Karma unit tests until all watchers are finished. 13 | var LOCK_FILE = '.atscriptwatcher'; 14 | var fs = require('fs'); 15 | 16 | if (fs.existsSync(LOCK_FILE)) { 17 | var lockCount = parseInt(fs.readFileSync(LOCK_FILE).toString(), 10); 18 | lockCount++; 19 | fs.writeFileSync(LOCK_FILE, lockCount.toString()); 20 | } else { 21 | fs.writeFileSync(LOCK_FILE, '1'); 22 | } 23 | 24 | 25 | // TODO(vojta): Fix this in Traceur instead. 26 | // Traceur generates source map file in the CWD. 27 | // This hacks Traceur to generate source map file in the output file directory, respecting the `sourceRoot` option. 28 | var writeFile = require('traceur/src/node/file-util').writeFile; 29 | compiler.writeTreeToFile = function(tree, filename) { 30 | filename = this.normalize(filename); 31 | // This is changed. 32 | // Pass sourceRoot to `this.write`. Traceur does not pass it through. 33 | var compiledCode = this.write(tree, filename, sourceRoot); 34 | if (this.options_.sourceMaps === 'file') { 35 | var sourcemap = this.getSourceMap(); 36 | if (sourcemap) { 37 | // This is changed. 38 | // Generate the source map in the same folder as the output JS file. 39 | writeFile(filename.replace(/\.js$/, '.map'), sourcemap); 40 | } 41 | } 42 | 43 | writeFile(filename, compiledCode); 44 | }; 45 | 46 | 47 | compiler.compileSingleFile(inputFilename, outputFilename, function(err) { 48 | console.error(err); 49 | }); 50 | 51 | // Release/decrement the lock. 52 | var lockCount = parseInt(fs.readFileSync(LOCK_FILE).toString(), 10); 53 | lockCount--; 54 | 55 | if (lockCount === 0) { 56 | fs.unlinkSync(LOCK_FILE); 57 | } else { 58 | fs.writeFileSync(LOCK_FILE, lockCount.toString()); 59 | } 60 | --------------------------------------------------------------------------------