• Aucun résultat trouvé

6.5 Common Patterns

6.5.2 Evolution Patterns

In this subsection, we describe the patterns we used to handle evolution. The main problem that we had to face, while evolving entities, was that when major changes were applied, the translation of the state from the old entities to new ones was not as simple as it seemed to be at first. The state had to be translated, split or unified at some point. This is not true for minor changes for which the built-in state transfer functionality was always suffi-cient. More complex changes are made through the composition of several of these patterns (possibly also with previously presented patterns). Note that these patterns are all particular to LuckyJ programming.

State Translation Pattern

Use: It actually happened that the appropriate version for recovering the state of an entity did not exist at a time. This particularly occured when some entity was replaced by an entity that was completely dif-ferent. The solution we used was then to use a temporary entity, to make the translation of states. We particularly used this pattern in development phasis, when entities could not have been fully tested yet.

Principle: As shown in figure 6.20, the entity E1 is replaced by the entity E2 in which the state is translated to fit the description needed by entity E3. E2 is then replaced by E3.

Entities: It has been used when evolving HttpdEntity, and PostItManager entity.

Figure 6.20: State Translation Pattern.

Entity Splitting Pattern

Use: This pattern is intended to allow the splitting of an entity into several others. Concerning services this does not mean any problem but con-cerning the state to be transfered, this was not a native functionality of the platform.

6.5. COMMON PATTERNS 135 Principle: In figure 6.21 we present the splitting pattern, ①

E1 and has E1’s state transfered to it; ②

loads an entity E3 that calls this service. E3 gets an answer and is

initialized; ③ E2 d

this service. E4 gets an answer and is initialized; ④

Note first that E2 and E4 may be merged into one entity, thus having no need for step ③

loading of E3 and/or E4 may be used to build SD1 or SD3. In that case, the service declaration takes place after the loading.

Entities: This pattern has been often used when delocalizing functionali-ties from HttpdEntity to other entifunctionali-ties (for instance MonitoringEntity).

Figure 6.21: Entity Splitting Pattern.

136 CHAPTER 6. PROGRAMMING WITH LUCKYJ Entity Unification Pattern

Use: This pattern is intended to allow the unification of two entities into only one.

Principle: In figure 6.22 we present the unification pattern,① E1 and has E1’s state transfered to it. ②

state transfered to it. ③

service using SD1. E3 calls this service using SD2, thus transferring E1’s state into E5. E5 unloads E3. ④

SD3, thus transferring E2’s state into E5. E5 unloads E4. Note that E4 and E5 may be merged in one entity, thus having no need for step

④ .

Entities: We did use this pattern only a few times, mainly when coming back to anolder version of the architecture.

Figure 6.22: Entity Unification Pattern.

6.5.3 Discussion

In this section we have explained a rather short number of programming patterns and evolution patterns we frequently used while programming with

6.6. CONCLUSION 137 LuckyJ. What is important to note is that we made an artificial difference between evolution patterns (patterns in which an evolution operation took place) and programming patterns (that may be found in pattern best prac-tices). Our point is that there is no difference between those two types of patterns. The evolution is a simple programming operation that may just be integrated in the programming experience itself. The added value of this whole work on programming patterns for LuckyJ is probably just that: dy-namic evolution can be considered as a programming style rather than a special operation, it is only another tool in the hands of developpers

6.6 Conclusion

In this chapter we presented some applications that we programmed on top of LuckyJ. The three applications we have shown mainly reflect three points:

It is easy for inexperienced programmers to code using LuckyJ: second years students had programmed LuckyJ applications after a two hours explanation and with the use of the only APIs.

Dynamic unanticipated evolution is now a possibility for programs coded in Java and our solution is modular and allows to make ar-bitrary changes on applications programmed in a type-safe language (unlike any other approach). It does not imply though that there is any notion of type-safety in our approach as we discuss it in chapter 8.

Due to the LuckyJ model allowing distribution, it is possible to code applications as if they were locals and transform these applications effortlessly into distributed ones.

We also presented some elements showing how to program LuckyJ enti-ties. In the following chapter we explain how the concepts and tools devel-oped in this work could be applied to other fields.

138 CHAPTER 6. PROGRAMMING WITH LUCKYJ

Chapter 7

Application Domains

We showed in the previous chapters that our model is adapted to the dynamic evolution of code and to distributed application evolution, but its application domains are wider. This is due to the fact that the work we presented in the previous chapters is contiguous to a large number of other fields. In this chapter, we give a brief overview on the possible applicable fields where our model could be used.

7.1 Unanticipated Dynamic Evolution

Our model has been designed to ease unanticipated dynamic evolution by decoupling entities dependencies. It is realized through the use of our com-munication model and the service descriptions. This works quite well mainly because of the following reasons:

1. There is no direct reference from one entity to another.

2. There is no direct reference from a piece of code to another.

3. Code failure is considered as a normal case.

It addresses the problem of unanticipated dynamic evolution because:

the programming platform allows to make arbitrary changes anytime without stopping the application.

changes are handled at the platform level.

This allows us to make arbitrary changes without perturbating the rest of the application. It is obvious that a part of the difficulty for handling seamless evolution of programs will be left to the programmer unless some specific

139

140 CHAPTER 7. APPLICATION DOMAINS development interfaces are built. First of all, programmers have to use the inter-entity infrastructure to make entities communicate. Second, program-mers have to handle themselves code failure.

To help programmers, we provided a certain number of facilities. Service descriptions are as lightweight as possible but may be extended at will in or-der to have more complex objects to be matched rather than only compound of primitive types. The way to do this is to extend theLJDescriptionObject class and override the match method. The intensively used tags to handle long-term communications, as well as service announcements, allow to dis-pose of delegation mechanisms that could be used to build repositories of service calls.

These points allow us to build a complete framework that may be used to handle evolution problems and test a large number of ideas. As far as it has been tested, our solution appears to be a realistic one that gives good results for dynamic unanticipated software evolution. Nevertheless it may be argued that our model is not applicable at an object/class granularity because of the very high cost in terms of computing power for the matching mechanism. As far as we know, this may be absolutely true. Our main contribution in this field probably lies in the fact that we bring the idea of modifying the object reference mechanism.

In future work, however, it would probably be interesting to adapt the model we described at a lower level of granularity. This idea implies a strong change in the object binding mechanism (which could be called object lookup mechanism at this point). Indeed, traditionally, the object lookup is not a matter of discussion in the object-oriented programming languages paradigm:

it is a reference that allows to control the object. In the more general world of object-orientation, the field that had been concerned in having a different object lookup mechanism is the object-oriented databases field. We strongly believe that building an object lookup mechanism pending to the model we described in this thesis would benefit greatly to object-oriented programming in terms of runtime evolution as well as modularity. Nevertheless, it is prob-able that, to make it suitprob-able in terms of performance, service descriptions should be reworked and code failure treatments should be automated.