You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).
382
383
- If the dependency exists AngularJS pass it as parameter to the component, which requires it.
@@ -427,6 +428,7 @@ This way the services are actually singletons but not implemented through the Si
427
428
428
429
- 增强代码的可测试性
429
430
- 控制单例对象的创建 (在本节例子中,IoC 容器通过懒惰式单例实例化方式帮我们进行控制)
431
+
430
432
<!--
431
433
- It improves the testability of your source code
432
434
- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)
@@ -437,13 +439,19 @@ This way the services are actually singletons but not implemented through the Si
437
439
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.
>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.
In the code above we use the `config` callback in order to define new "provider". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.
Each service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.
482
+
-->
469
483
484
+
让我们更深入的来看看 AngularJS 中是如何实现的:
485
+
<!--
470
486
We can dig a little bit deeper in AngularJS' implementation:
487
+
-->
471
488
472
489
```JavaScript
473
490
//...
@@ -511,29 +528,52 @@ function invoke(fn, self, locals, serviceName){
511
528
}
512
529
```
513
530
531
+
从以上例子中,我们注意到 `$get` 函数被下面的代码使用:
532
+
<!--
514
533
From the example above we can notice how the `$get` method is actually used:
The snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.
If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product".
There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:
553
+
-->
554
+
555
+
- 最恰当的时候来完成组件所需的实例化过程
556
+
- 解决组件所需的所有依赖关系
557
+
- 给定组件所允许存在的实例个数 (对于 service 和 filter 来说只有一个,而 controller 可以有多个实例)
525
558
559
+
<!--
526
560
- The most appropriate moment, when the component needs to be instantiated
527
561
- Resolving all the dependencies required by the component
528
562
- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)
>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.
AngularJS 已经提供了这种方式来扩展/增强现有 service 的功能。在这里通过使用 `$provide` 的 `decorator` 函数,我们可以在第三方已经定义和使用的 service 上创建一个“wrapper”:
574
+
<!--
536
575
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:
The example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `"foo"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.
566
609
We decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.
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).
0 commit comments