From cc8c9bfa95af5d20fedd38c9be20dac052104db6 Mon Sep 17 00:00:00 2001 From: mgechev Date: Mon, 13 Apr 2015 10:25:27 +0300 Subject: [PATCH 1/7] Update toc --- README.md | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2535654..c7240bd 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,13 @@ * [Directives](#directives) * [Filters](#filters) * [Services](#services) +* [Angular 2 overview](#angular-2-overview) + * [Components](#components) + * [Services](#services) + * [Dependency Injection](#dependency-injection) + * [Zones](#zones) * [AngularJS Patterns](#angularjs-patterns) - * [Services](#services-1) + * [Catalog](#catalog) * [Singleton](#singleton) * [Factory Method](#factory-method) * [Decorator](#decorator) @@ -23,19 +28,37 @@ * [Proxy](#proxy) * [Active Record](#active-record) * [Intercepting Filters](#intercepting-filters) - * [Directives](#directives-1) * [Composite](#composite) - * [Interpreter](#interpreter) * [Template View](#template-view) - * [Scope](#scope-1) * [Observer](#observer) * [Chain of Responsibilities](#chain-of-responsibilities) * [Command](#command) - * [Controller](#controller-1) * [Page Controller](#page-controller) - * [Others](#others) * [Module Pattern](#module-pattern) - * [Data Mapper](#data-mapper) + * [Data Mapper](#data-mapper) + * [AngularJS](#angularjs) + * [Services](#services-1) + * [Singleton](#singleton) + * [Factory Method](#factory-method) + * [Decorator](#decorator) + * [Facade](#facade) + * [Proxy](#proxy) + * [Active Record](#active-record) + * [Intercepting Filters](#intercepting-filters) + * [Directives](#directives-1) + * [Composite](#composite) + * [Interpreter](#interpreter) + * [Template View](#template-view) + * [Scope](#scope-1) + * [Observer](#observer) + * [Chain of Responsibilities](#chain-of-responsibilities) + * [Command](#command) + * [Controller](#controller-1) + * [Page Controller](#page-controller) + * [Others](#others) + * [Module Pattern](#module-pattern) + * [Data Mapper](#data-mapper) + * [Angular 2](#angular2) * [References](#references) From d8530088fbcd3b9a69e03064a8d8ef771c2dca79 Mon Sep 17 00:00:00 2001 From: mgechev Date: Mon, 13 Apr 2015 10:26:45 +0300 Subject: [PATCH 2/7] Fix toc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7240bd..ffa5b6c 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ * [Others](#others) * [Module Pattern](#module-pattern) * [Data Mapper](#data-mapper) - * [Angular 2](#angular2) + * [Angular 2](#angular-2) * [References](#references) From 8e1cb637538eb1c8b23953702223beb6f667e5f8 Mon Sep 17 00:00:00 2001 From: mgechev Date: Wed, 6 May 2015 09:19:50 -0700 Subject: [PATCH 3/7] Externalize the patterns update content --- README.md | 132 ++++++++++------------------------------------ patterns-list.md | 134 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 103 deletions(-) create mode 100644 patterns-list.md diff --git a/README.md b/README.md index 35f5dc1..24e6369 100644 --- a/README.md +++ b/README.md @@ -19,23 +19,7 @@ * [Services](#services) * [Dependency Injection](#dependency-injection) * [Zones](#zones) -* [AngularJS Patterns](#angularjs-patterns) - * [Catalog](#catalog) - * [Singleton](#singleton) - * [Factory Method](#factory-method) - * [Decorator](#decorator) - * [Facade](#facade) - * [Proxy](#proxy) - * [Active Record](#active-record) - * [Intercepting Filters](#intercepting-filters) - * [Composite](#composite) - * [Template View](#template-view) - * [Observer](#observer) - * [Chain of Responsibilities](#chain-of-responsibilities) - * [Command](#command) - * [Page Controller](#page-controller) - * [Module Pattern](#module-pattern) - * [Data Mapper](#data-mapper) +* [AngularJS in Patterns](#angularjs-in-patterns) * [AngularJS](#angularjs) * [Services](#services-1) * [Singleton](#singleton) @@ -59,6 +43,17 @@ * [Module Pattern](#module-pattern) * [Data Mapper](#data-mapper) * [Angular 2](#angular-2) + * [Components](#components-1) + * [Composite](#composite-2) + * [Memento](#memento) + * [Interpreter](#interpreter-2) + * [Visitor](#visitor) + * [Strategy](#strategy) + * [Builder](#builder) + * [Adapter](#adapter) + * [Facade](#facade-2) + * [Object Pool](#object-pool) + * [References](#references) @@ -276,7 +271,7 @@ function MyCtrl(Developer) { } ``` -## AngularJS Patterns +## AngularJS in Patterns In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components. @@ -284,13 +279,7 @@ In the last chapter we are going to take a look at some architectural patterns, ### Services -#### Singleton - ->The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. - -In the UML diagram bellow is illustrated the singleton design pattern. - -![Singleton](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg "Fig. 1") + When given dependency is required by any component, AngularJS resolves it using the following algorithm: @@ -338,9 +327,7 @@ For further discussion on this topic Misko Hevery's [article](http://googletesti #### Factory Method ->The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor. - -![Factory Method](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg "Fig. 2") + Lets consider the following snippet: @@ -428,9 +415,7 @@ There are a few benefits of using the factory method pattern in this case, becau #### Decorator ->The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. - -![Decorator](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg "Fig. 4") + AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create "wrapper" of any service you have previously defined or used by a third-party: @@ -468,17 +453,7 @@ Using this pattern is especially useful when we need to modify the functionality #### Facade ->A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can: - ->1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks; - ->2. make the library more readable, for the same reason; - ->3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system; - ->4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs). - -![Facade](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg "Fig. 11") + There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade. @@ -527,9 +502,7 @@ Even higher level of abstraction is being created by `$resource`, which is build #### Proxy ->A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. - -![Proxy](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg "Fig. 9") + We can distinguish three different types of proxy: @@ -565,9 +538,7 @@ Initially when the snippet above executes, the property `user` of the `$scope` o #### Active Record ->The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication. - -![Active Record](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg "Fig. 7") + AngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core. @@ -608,9 +579,7 @@ Since Martin Fowler states that #### Intercepting Filters ->Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request. - -![Composite](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg "Fig. 3") + In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one. @@ -637,9 +606,7 @@ $httpProvider.interceptors.push(function($q, dependency1, dependency2) { #### Composite ->The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. - -![Composite](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg "Fig. 3") + According to the Gang of Four, MVC is nothing more than combination of: @@ -686,9 +653,7 @@ In the second, JavaScript, example we see that the `template` property of the di ### Interpreter ->In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence. - -![Interpreter](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg "Fig. 6") + Behind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions: @@ -756,9 +721,7 @@ Few sample AngularJS expressions are: #### Template View -> Renders information into HTML by embedding markers in an HTML page. - -![Template View](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg "Fig. 8") + The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format. @@ -813,9 +776,7 @@ will produce the same result as the one above. The main difference here is that #### Observer ->The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. - -![Observer](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg "Fig. 7") + There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes. @@ -849,9 +810,7 @@ In the JavaScript community this pattern is better known as publish/subscribe. #### Chain of Responsibilities ->The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain. - -![Chain of Responsibilities](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg "Fig. 5") + As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property. @@ -886,9 +845,7 @@ The different handlers from the UML diagram above are the different scopes, inje #### Command ->In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters. - -![Command](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg "Fig. 11") + Before continuing with the application of the command pattern lets describe how AngularJS implements data binding. @@ -931,9 +888,7 @@ We can think of the `watcher` object as a command. The expression of the command #### Page Controller ->An object that handles a request for a specific page or action on a Web site. Martin Fowler - -![Page Controller](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg "Fig. 8") + According to [4](#references) the page controller: @@ -983,34 +938,7 @@ The `ChildCtrl` is responsible for handling actions such as clicking the button #### Module Pattern -This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy. - -Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module: - -```javascript -var Page = (function () { - - var title; - - function setTitle(t) { - document.title = t; - title = t; - } - - function getTitle() { - return title; - } - - return { - setTitle: setTitle, - getTitle: getTitle - }; -}()); -``` - -In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable. - -In this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE. + The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy: @@ -1037,9 +965,7 @@ Once we want to inject `foo` inside any other component we won't be able to use ### Data Mapper ->A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself. - -![Data Mapper](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg "Fig. 10") + As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.). diff --git a/patterns-list.md b/patterns-list.md new file mode 100644 index 0000000..45edfe4 --- /dev/null +++ b/patterns-list.md @@ -0,0 +1,134 @@ + +#### Singleton + +>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. + +In the UML diagram bellow is illustrated the singleton design pattern. + +![Singleton](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg "Fig. 1") + + + +>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor. + +![Factory Method](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg "Fig. 2") + + + + +>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. + +![Decorator](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg "Fig. 4") + + + +>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can: + +>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks; + +>2. make the library more readable, for the same reason; + +>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system; + +>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs). + +![Facade](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg "Fig. 11") + + + +>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. + +![Proxy](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg "Fig. 9") + + + +>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication. + +![Active Record](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg "Fig. 7") + + + +>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request. + +![Intercepting Filters](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg "Fig. 3") + + + +>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. + +![Composite](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg "Fig. 3") + + + +>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence. + +![Interpreter](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg "Fig. 6") + + + +> Renders information into HTML by embedding markers in an HTML page. + +![Template View](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg "Fig. 8") + + + +>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. + +![Observer](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg "Fig. 7") + + + +>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain. + +![Chain of Responsibilities](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg "Fig. 5") + + + +>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters. + +![Command](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg "Fig. 11") + + + +>An object that handles a request for a specific page or action on a Web site. Martin Fowler + +![Page Controller](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg "Fig. 8") + + + +This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy. + +Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module: + +```javascript +var Page = (function () { + + var title; + + function setTitle(t) { + document.title = t; + title = t; + } + + function getTitle() { + return title; + } + + return { + setTitle: setTitle, + getTitle: getTitle + }; +}()); +``` + +In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable. + +In this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE. + + + +>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself. + +![Data Mapper](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg "Fig. 10") + + From 35cec84aa6b5f67e6ddb91269dfec6444292364e Mon Sep 17 00:00:00 2001 From: mgechev Date: Wed, 6 May 2015 09:20:32 -0700 Subject: [PATCH 4/7] Update table of content --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 24e6369..e2b3457 100644 --- a/README.md +++ b/README.md @@ -43,16 +43,15 @@ * [Module Pattern](#module-pattern) * [Data Mapper](#data-mapper) * [Angular 2](#angular-2) - * [Components](#components-1) - * [Composite](#composite-2) - * [Memento](#memento) - * [Interpreter](#interpreter-2) - * [Visitor](#visitor) - * [Strategy](#strategy) - * [Builder](#builder) - * [Adapter](#adapter) - * [Facade](#facade-2) - * [Object Pool](#object-pool) + * [Composite](#composite-2) + * [Memento](#memento) + * [Interpreter](#interpreter-2) + * [Visitor](#visitor) + * [Strategy](#strategy) + * [Builder](#builder) + * [Adapter](#adapter) + * [Facade](#facade-2) + * [Object Pool](#object-pool) * [References](#references) From 0e561d7a73b4cbdf05583abbba450782e5838766 Mon Sep 17 00:00:00 2001 From: mgechev Date: Wed, 6 May 2015 09:24:47 -0700 Subject: [PATCH 5/7] Update readme --- README.md | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index e2b3457..8eff7b1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ * [Directives](#directives) * [Filters](#filters) * [Services](#services) -* [Angular 2 overview](#angular-2-overview) +* [Angular 2 Overview](#angular-2-overview) * [Components](#components) * [Services](#services) * [Dependency Injection](#dependency-injection) @@ -270,13 +270,15 @@ function MyCtrl(Developer) { } ``` +## Angular 2 Overview + ## AngularJS in Patterns -In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components. +In the next a couple of sections, we are going to take a look at how the traditional design and architectural patterns are composed in the AngularJS components. The following chapter is devided in two parts - AngularJS 1.x and Angular 2. In the corresponding chapters the patterns will be put in the appropriate context. -In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS. +### AngularJS 1.x -### Services +#### Services @@ -324,7 +326,7 @@ This way the services are actually singletons but not implemented through the Si For further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered. -#### Factory Method +##### Factory Method @@ -412,7 +414,7 @@ There are a few benefits of using the factory method pattern in this case, becau - Resolving all the dependencies required by the component - The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers) -#### Decorator +##### Decorator @@ -450,7 +452,7 @@ We decorate the service by overriding its method `bar`. The actual decoration is Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop). -#### Facade +##### Facade @@ -499,7 +501,7 @@ The second option provides pre-configured version, which creates a HTTP POST req Even higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections. -#### Proxy +##### Proxy @@ -535,7 +537,7 @@ function MainCtrl($scope, $resource) { ``` Initially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view. -#### Active Record +##### Active Record @@ -576,7 +578,7 @@ Since Martin Fowler states that `$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication". -#### Intercepting Filters +##### Intercepting Filters @@ -601,9 +603,9 @@ $httpProvider.interceptors.push(function($q, dependency1, dependency2) { }); ``` -### Directives +#### Directives -#### Composite +##### Composite @@ -650,7 +652,7 @@ From the first example we can note that the whole DOM tree is a composition of e In the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node. -### Interpreter +#### Interpreter @@ -718,7 +720,7 @@ Few sample AngularJS expressions are: (foo) ? bar : baz | toUpperCase ``` -#### Template View +##### Template View @@ -771,9 +773,9 @@ $scope.names = ['foo', 'bar', 'baz']; will produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead. -### Scope +#### Scope -#### Observer +##### Observer @@ -807,7 +809,7 @@ Each scope can subscribe to any event with multiple callbacks (i.e. it can assoc In the JavaScript community this pattern is better known as publish/subscribe. -#### Chain of Responsibilities +##### Chain of Responsibilities @@ -842,7 +844,7 @@ myModule.controller('ChildCtrl', function ($scope) { The different handlers from the UML diagram above are the different scopes, injected to the controllers. -#### Command +##### Command @@ -883,9 +885,9 @@ $watch: function(watchExp, listener, objectEquality) { We can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`"$digest"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`. -### Controllers +#### Controllers -#### Page Controller +##### Page Controller @@ -933,9 +935,9 @@ This example aims to illustrates the most trivial way to reuse logic by using a The `ChildCtrl` is responsible for handling actions such as clicking the button with label `"Click"` and exposing the model to the view, by attaching it to the scope. -### Others +#### Others -#### Module Pattern +##### Module Pattern @@ -962,7 +964,7 @@ app.factory('foo', function () { Once we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library. -### Data Mapper +#### Data Mapper From bc0ac6914104aaa631123ab99da916e53810a1f9 Mon Sep 17 00:00:00 2001 From: mgechev Date: Wed, 6 May 2015 10:20:50 -0700 Subject: [PATCH 6/7] Add components and services section --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/README.md b/README.md index 8eff7b1..39c201d 100644 --- a/README.md +++ b/README.md @@ -272,6 +272,58 @@ function MyCtrl(Developer) { ## Angular 2 Overview +Angular 2 is the latest version of the AngularJS framework and it in moment of writing this document its design and development are still in progress. The entire structure of the framework and all the components are reconsidered so there are a lot of changes. Angular 2 is developed in TypeScript it contains minimal set of components compared to AngularJS 1.x so some people think of it more like a library rather than a framework. In the following sections we are going to describe most of these components. Since complete introduction to the framework is out of the scope of this paper, in the resource section there are links to getting started documents and blog posts. + +### Components + +The main building blocks of all Angular 2 applications are the components. We can think of the Angular 2 components as directives, which render the UI based on some state, stored inside them. This idea might seems quite familiar from ReactJS and basically it is. The main differences between the Angular 2 components and ReactJS are the mechanisms the data-binding is being implemented and the template processing. In Angular 2 the templates are consisted of actual markup, which is being inserted into the DOM and processed recursively based on other components found. However, in ReactJS we define our component using language called JSX, which is later transpiled to explicit JavaScript method calls. + +The business logic of your application should be isolated in separate services, outside the actual components. + +```javascript +// example components +``` + +### Services + +Similarly to AngularJS 1.x, Angular 2 has services, however the syntax for defining them is completely different. In Angular 2 the services are simply TypeScript classes, which could be injected inside other services or components using the dependency injection mechanism of Angular 2. Responsibilities to the services in Angular 2 are to encapsulate the business logic, implement the interaction with remote services and create injectable adapters to browser APIs (for example `localStorage`). + +Here is an example of a service, which defines store of users: + +```javascript +class UsersList { + users:List; + constructor() { + this.users = new List(); + } + add(user:User) { + this.users.push(User); + } + remote(user:User) { + this.users.remove(user); + } + fetchAll() { + let xhr = new XHR(); + return xhr.get('/users') + .then((users) => { + users.forEach((u) => { + this.users.add(new User(u)); + }); + return this.users; + }); + } + fetch(id:Number) { + let xhr = new XHR(); + return xhr.get(`/users/${id}`) + .then((user) => { + let u = new User(user); + this.users.add(u); + return u; + }); + } +} +``` + ## AngularJS in Patterns In the next a couple of sections, we are going to take a look at how the traditional design and architectural patterns are composed in the AngularJS components. The following chapter is devided in two parts - AngularJS 1.x and Angular 2. In the corresponding chapters the patterns will be put in the appropriate context. From e7a8ba33d2f00c1b6af27d7f4d1878d0af95390a Mon Sep 17 00:00:00 2001 From: mgechev Date: Wed, 6 May 2015 10:29:20 -0700 Subject: [PATCH 7/7] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39c201d..23b7b79 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ class UsersList { add(user:User) { this.users.push(User); } - remote(user:User) { + remove(user:User) { this.users.remove(user); } fetchAll() {