1 | Understand the Concepts
|
2 | =======================
|
3 |
|
4 | [←](index.md)
|
5 |
|
6 | Object-Oriented Programming (OOP)
|
7 | ---------------------------------
|
8 |
|
9 | This part is going to be short. OOP is a way to develop big and complex applications for a long time now. Most commonly used languages are designed for that. Theoretical and empirical ways of coding with OOP are mature and allow to structure and develop robust applications.
|
10 |
|
11 | However, native javascript does not provide all features you need to make a powerful OOP code. Danf implements an OOP layer allowing to handle that problematic.
|
12 |
|
13 | Service Oriented Architecture (SOA)
|
14 | -----------------------------------
|
15 |
|
16 | SOA is often thought at a webservice level but is also the base of a strong factored OOP code.
|
17 |
|
18 | Let's see an example of a pure OOP code where you want to sell a product in a store to a customer:
|
19 | ```javascript
|
20 | var store = new Store(),
|
21 | product = new Product(),
|
22 | customer = new Customer()
|
23 | ;
|
24 |
|
25 | // A first possibility.
|
26 | store->sell(product, customer);
|
27 |
|
28 | // A second possibility.
|
29 | product->buy(store, customer);
|
30 |
|
31 | // ...
|
32 | ```
|
33 |
|
34 | This almost automatically leads to have duplicated codes very hard to maintain:
|
35 | * You have to test each code.
|
36 | * If one code evolves, you must not forget the other one.
|
37 |
|
38 | Of course, you can try to only have one implemented method. But where? In `Product`? `Store`? `Customer`? And how to be sure it is implemented only once?
|
39 |
|
40 | A better way, to handle that is to use a "service" (SOA pattern):
|
41 | ```javascript
|
42 | var store = new Store(),
|
43 | product = new Product(),
|
44 | customer = new Customer(),
|
45 | saleHandler = new SaleHandler()
|
46 | ;
|
47 |
|
48 | saleHandler->sell(product, store, customer);
|
49 | ```
|
50 | The handler `saleHandler` is a service which is responsible for sales. He has the intelligence to manipulate data objects like `store`, `product` or `customer`.
|
51 | This way, your code is factored and your developement is rationalized.
|
52 |
|
53 | Composition and low coupling
|
54 | ----------------------------
|
55 |
|
56 | ### Composition vs inheritance
|
57 |
|
58 | Lots of developers use inheritance to factorize code between classes. Of course it is not a bad idea, but it should be used in a strict delimited way. Multiple inheritance has many problems (diamond, complexity, ...) which often lead to a code difficult to maintain. In Danf, single inheritance is the rule. The framework encourages to use inheritance only when the parent and the child class have the same responsability.
|
59 |
|
60 | Let's keep the previous example. Imagine, there are 3 sale entities in the company (clothing, perfume, jewel). This results in 3 `SaleHandler` child classes defining a method `getAfterSalesServicePhone()`. Child classes are sale handlers as their parent, so inheritance is fine. Now, imagine we want to log sales. Is it a good idea to make an abtract loggable class and make our child classes inherit from it? The response is obviously no! The way to handle it is simple:
|
61 | ```javascript
|
62 | var clothingSaleHandler = new ClothingSaleHandler(),
|
63 | perfumeSaleHandler = new PerfumeSaleHandler(),
|
64 | jewelSaleHandler = new JewelSaleHandler(),
|
65 | logger = new Logger()
|
66 | ;
|
67 |
|
68 | clothingSaleHandler->setLogger(logger);
|
69 | perfumeSaleHandler->setLogger(logger);
|
70 | jewelSaleHandler->setLogger(logger);
|
71 | ```
|
72 |
|
73 | The responsability of a sale handler is not to log or be loggable but to handle sales. This is why composition must be used instead of inheritance. Here, the logging factored code is in the class `Logger`.
|
74 |
|
75 | ### Low coupling
|
76 |
|
77 | Coupling is the degree of interaction between two classes. In an inheritance relation, the coupling is maximum: the child is fully dependent on its parent. This kind of coupling is really hard to change. In a simple composition relation, the coupling is the same as in an inheritance. However, it is possible to reduce this dependency by defining interfaces between classes.
|
78 |
|
79 | Imagine, `Logger` has 30 methods. Sale handlers only need to call method `log()`. Then, a sale handler only need an object from a class implementing the interface `LoggerInterface` defining `log()`.
|
80 |
|
81 | You can easily see the resulting benefits:
|
82 | * Scalability: you can change the class `Logger` by another one implementing `LoggerInterface`.
|
83 | * Maintenability: you can understand real dependencies between classes at a glance.
|
84 | * Testability: you can mock dependencies just implementing the interfaces.
|
85 |
|
86 | Danf allows to define and ensure interfaces to reduce coupling. This concept is important because it is the basis for using the dependency injection to its full potential and dependency injection is the basis for a strong OOP architecture. Dependency injection in Danf is explained in the next section.
|
87 |
|
88 | Inversion of Control (IoC)
|
89 | --------------------------
|
90 |
|
91 | Danf handle the flow of control of your application for you. All you have to do is implement your classes and use the configuration to describe all the interactions.
|
92 |
|
93 | A strong dependency injection component allows you to declare services from your classes and then inject them into each others. If you are coming from the PHP community, you will notice some similarity with the dependency injection of Symfony2.
|
94 |
|
95 | Event driven
|
96 | ------------
|
97 |
|
98 | This framework does not forget the spirit of javascript and Node: events drive the flow. In Danf, you will be able to handle all incoming events the same way. For instance, a HTTP request event will be handled as a click on an element in the browser.
|
99 | Moreover, the way the events are handled gives a pretty easy alternative to callback hell.
|
100 |
|
101 | [←](index.md) |
\ | No newline at end of file |