27
How Angular Embraced Traditional OOP Design Patterns Ran Mizrahi (@ranm8) Open Source Dpt. Leader @ CodeOasis

How AngularJS Embraced Traditional Design Patterns

Embed Size (px)

DESCRIPTION

Ran Mizrahi talks about how AngularJS embraced traditional design patterns and used the benefits of JavaScript for that cause.

Citation preview

Page 1: How AngularJS Embraced Traditional Design Patterns

How Angular Embraced Traditional OOP Design

Patterns

Ran Mizrahi (@ranm8)Open Source Dpt. Leader @ CodeOasis

Page 2: How AngularJS Embraced Traditional Design Patterns

About CodeOasis

• CodeOasis specializes in cutting-edge web solutions.!

• Large variety of customers (from startups to enterprises).!

• We’re passionate about JavaScript (-:!

• Technologies we love:!

• Play Framework• AngularJS • nodeJS • HTML5• CSS3!

• Our Microsoft department works with C#, WPF, etc.

Page 3: How AngularJS Embraced Traditional Design Patterns

Implementing Design Patterns in

JavaScript

Page 4: How AngularJS Embraced Traditional Design Patterns

Implementing Design Patterns in JavaScript

• Classes.!

• Interfaces.!

• Inheritance.!

• Encapsulation.!

• Polymorphism.

Most traditional object-oriented languages

Page 5: How AngularJS Embraced Traditional Design Patterns

var User = new Class({ initialize: function(name) { this.name = name; }, setEmail: function(mail) { this.mail = mail; } }); !var someUser = new User('Ran Mizrahi');

We don’t have classes…

* MooTools Example

Implementing Design Patterns in JavaScript

Page 6: How AngularJS Embraced Traditional Design Patterns

We don’t have interfaces…

* Taken from the book “Pro JavaScript Design Patterns”

Implementing Design Patterns in JavaScript

var DynamicMap = new Interface('DynamicMap', ['centerOnPoint', 'zoom', 'draw']); !function displayRoute(mapInstance) { Interface.ensureImplements(mapInstance, DynamicMap); ! mapInstace.centerOnPoint(12, 34); mapInstace.draw(5); mapInstace.zoom(); }

Page 7: How AngularJS Embraced Traditional Design Patterns

var User = new Class({ ! extends: BaseUser, initialize: function(name) { this.name = name; }, setEmail: function(mail) { this.mail = mail; } }); !var someUser = new User('Ran Mizrahi');

We don’t have classical inheritance..

* MooTools Example

Implementing Design Patterns in JavaScript

Page 8: How AngularJS Embraced Traditional Design Patterns

Stop Forcing It!

Page 9: How AngularJS Embraced Traditional Design Patterns

Embrace It!

Page 10: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

“When I see a bird that walks like a duck and sounds like a duck, I call that bird a duck”

— James Whitcomb Riley

Page 11: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

function isWindow(obj) { return obj && obj.document && obj.location && obj.alert && obj.setInterval; }

This is how a duck looks like…

* Angular implementation of the isWindow method…

Page 12: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

JavaScript is simple (can be explained over a beer) and makes us write less code…

Java:!  List<Book> books = new ArrayList<Book>();!!JavaScript:!  var books = [];!

Page 13: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

Object is a unit responsible for state and behaviour and JavaScript function has them both.

function Unit() { var state; ! function behaviour() { // Some behaviour } return function() { // Do something } }

Page 14: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

We don’t have visibility keywords (e.g. private, protected, public) but we do have closuresvar Service = (function(window, undefined) { // Private function base64Encode(string) { return window.btoa(string); } // Public return { encode: function(string) { return base64Encode(string); } }; }(window));

Page 15: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScriptState management can be as easy by using constructor functions or closures…

function someFunction(baseUrl) { var config = { url: baseUrl }; return function() { return config.url + '/hey'; } };

function Duck(name) { // Object state this.name = name; }

Page 16: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

Polymorphism can be beautiful without interfaces, if it’s just a duck… function Duck() { // Private state here… ! // Public state return { walk: function() { // Walk like a duck return quack(); }, talk: function() { // Talk like a duck } }; }

function Bird() { // Private state here… ! // Public state return { walk: function() { // Walk like a bird return tweet(); }, talk: function() { // Talk like a bird } }; }

function talker(someBird) { // Make it talk someBird.talk(); }

Page 17: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

But what will happen if the duck won’t talk…

JavaScript has prototypical inheritance but yet, I don’t often feel I need to inherit anything (prefer polymorphic composition over inheritance).

Page 18: How AngularJS Embraced Traditional Design Patterns

Learning To Embrace JavaScript

For true coverage and confidence, compilers won’t do the job and they can’t replace real unit test coverage.

• Almost everything is mutable.!

• Easily stub anything.!

• Easily fake dependencies.

Page 19: How AngularJS Embraced Traditional Design Patterns

Design Patterns in AngularJS

Page 20: How AngularJS Embraced Traditional Design Patterns

MVC and Controllersangular.module('myModule') .controller('MyCtrl', ['$http', MyCtrl]); !// Dependencies are in closure (-: function MyCtrl($http) { var someState = {}; function doSomething() { // Closure is accessible. } }

• Controllers are just JavaScript function.

• They can encapsulate and preserve state by using closures.!

• Exposes behaviour with $scope.

Page 21: How AngularJS Embraced Traditional Design Patterns

Dependency Injection

• Simple dynamic dependency injection based on arrays and naming convention.

• Makes your code polymorphic by easily replacing your implementation.!

• Super easy to isolate and test.

angular.module('myModule') .controller('MyCtrl', ['$http', MyCtrl]); function MyCtrl($http) { $http.get('http://google.com').then(getTheMonkey); }

Page 22: How AngularJS Embraced Traditional Design Patterns

DecoratorDecorator is a pattern used to “decorate” functionality of certain object.

Page 23: How AngularJS Embraced Traditional Design Patterns

Decorator

Angular made service decoration really easy…

$provider.decorator('$log', ['delegate', function(delegate) { // Convert warning to error delegate.warn = delegate.error; // Return the decorated service return delegate; }]);

Ask for a function, manipulate it and return a new one (-:

Page 24: How AngularJS Embraced Traditional Design Patterns

FacadeA facade is an object that provides a simplified interface to a larger body of code and logic.

angular.module('myModule') .factory('ReallyComplicatedService', [Service]); !function Service($http) { // Do all the private stuff and handle the other library // Expose really simple interface return { get: function() { // Get it }, del: function() { // Delete it } }; }

Page 25: How AngularJS Embraced Traditional Design Patterns

SingletonSingletons is a design pattern that restricts the instantiation of a class to one object.var Singleton = (function() { function privateFunction() { // Do private stuff } return { someMethod: function() { // Do public stuff }, anotherMethod: function() { // Do some more public stuff } }; }());

JavaScript makes singleton really easy (-: But still, it’s global and hard to configure…

Page 26: How AngularJS Embraced Traditional Design Patterns

SingletonAngular used it and provided us with dependency injection to avoid singleton downsides among others.angular.module('myModule') .provider('myHttp', myHttp); function myHttp() { var baseUrl; this.baseUrl = function(value) { if (!value) { return baseUrl; } baseUrl = value; }; this.$get = ['$q', function() { // myHttp service implementation... }]; }

Page 27: How AngularJS Embraced Traditional Design Patterns

Questions?Thank you!