---
tags: MSE / semestre 2
---
# MSE - AdvSoftArchDes
## 1. Semaine 1 (Chapitre 1 - Définitions et ADLs)
### 1.1. Sally's Story
1. Intervenants (Stakeholders) :
* `endusers` : nécessaires pour obtenir les **requirements** ;
* `legal team`, `IT Group`, `management team`, `client`, ... .
2. Intérêts :
* Tous les intervenants ont des intérêts différents quand à la réalisation du produit ;
* Ces intérêts ne sont même parfois **pas compatibles**.
3. Roles :
* Finaliser les requirements ;
* Trouver des **consensus** entre les intérêts non-compatibles des intervenants ;
* Proposer une architecture adéquate ;
* L'architecte a également un rôle de garant sur la bonne implémentation de l'architecture qu'il a mis en place.
### 1.2. Definition
En gros le goal c'est de voir que suivant le "type" de personne/collectif, c'est-à-dire sa "fonction", on obtiendra une définition différente de ce qu'est une `Software Architecture` :
1. 
> Bah voilà quoi, c'est IEE, forcément très formelle.
2. 
> Bah c'étaient des développeurs. Donc très diriger sur le concret.
3. 
> Était un **manager**. Se focalise donc même sur la formalisation des besoins des Stakeholders **dans** l'architecture logicielle.
### 1.3. Trucs
* Waterfall : Analyse -> Conception -> Réalisation -> Test -> Déploiement.
- Les spécifications (requirements). Répond à la question : **Quoi ?**
- La conception (architecturelle et détaillée). Répond à la question : **Comment ?**
* Conception Architecturelle : Comment va s'articuler le système par composant, **sans rentrer dans le détail** ?
* Conception Détaillée -> Comment va s'articuler **individuellement et en détails** chaque composant ?
### 1.4. Viewpoint
1. Functional :
* Concerne les aspects fonctionnels purs du système (capacités fonctionnelles, les interfaces externes/internes, la philosophie du design du système). C'est-à-dire ce qui doit pouvoir être réalisés fonctionnellement (typiquement le `enduser`).
2. Information :
* Quelles sont les données manipulées ? Meilleures structures pour les store ? Faut les backups ? ... Cela à avoir avec les données.
3. Concurrency :
* Gère l'aspect concurrentiel ou non. C'est-à-dire littéralement si le système fonctionne en concurrence.
4. Development :
* Quels standards utilisés ? Quels types de tests vont être réalisés ? ... Concerne pûrement le développement.
5. Deployment :
* Description de l'environnement dans lequel le système va être déployé.
6. Operational :
* Décrit comment on va faire les trucs en fait. Typiquement comment on va faire les backups ? À la mano ?
### 1.5. Perspective

On représente typiquement les `Viewpoints` et les `Perspectives` de façon matricielle, car la réalisation d'une seule Perspective va foncièrement empiété sur plusieurs views en même temps.

### 1.6. Déliverables

1. Clarifier tout les besoins pour la réalisation du système : **elicitation**.
2. Gérer les intérvenants, leurs expectations et intérêts et trouver les meilleures alternativse : **compromis**.
3. Identifier et évaluer les alternatives architecturales réalisables et choisir l'optimale : **optimisation**.
4. Description du critère d'acceptation de l'architecture : **qualité**.
5. Définir les requirements et recommendations pour l'actual réalisation de l'architecture système (responsabilité de "garant" pour l'architecture) : **construction**.
## 2. Semaine 2 (Chapitre 2 - ADL et UML)
### 2.1. AD & ADL
1. ***A**rchitectural **D**escription (AD)* :

2. ***A**rchitectural **D**escription **L**angage (ADL)* :

### 2.2. Liste des modèles UML 2.0

### 2.3. Diagramme de classes
#### 2.3.1. Domain model diagram

> * **Association** = Ligne droite continue.
> * **Aggrégation** = Ligne droite continue diamant.
> * **Composition** = Ligne droite continue diamant rempli.
> * **Dépendance** = Flèche non-pleine discontinue (avec un verbe qui précise comme "use").
> * **Généralisation/Spécialisation** (Héritage) = Flèche droite pleine continue dans le sens de la généralisation (va au général).
> * **Implémentation/Réalisation** = Flèche pleine discontinue.
> * **Boundary** = La classe à la limite du système (ex: Button), communique avec les contrôleurs (là où il y a l'intelligence).
> * **Controller** = La classe qui va s'occuper à réaliser l'intelligence (ex: qui va aller supprimer qqch suite au clic du Button).
> * **Entity** = La classe qui correspond au stockage (ex: qui s'est fait supprimé par le controller suite au clic du Button).
> * **Cardinalité** = Combien d'éléments d'une classe peuvent être associés aux élément de l'autres classes.
#### 2.3.2. Implementation classes

> Va être rarement utilisé tel quel car trop précis.
### 2.4. Object Diagram

> * Une instanciation "particulière" d'un diagramme de classe au final.
> * Différence de diagramme entre classe et objet que ce dernier est **++souligné++**. Il n'y a en revanche, ici, pas d'héritage (évidemment). On est au niveau des objets ici.
> * Ici les objets sont véritablement précisés. Ils existent.
> * Et une précision/explication du diagramme de classe. Ce dernier est donc très peu utilisé également.
> * Mais dans des cas spécifiques, on peut vouloir réaliser les diagrammes de classes puis d'objets pour vérifier la cohérence générale du système.
### 2.5. Package Diagram

> * Le diagramme par Package est relativement **haut-niveau**. Il est possible de reprsenter beaucoup de choses avec, ce qui par essence en fait une représentation architecturale.
#### 2.5.1. Model diagram

> * Représente une application "**architecture 3-tiers**".
### 2.6. Component Diagram

> * Descriptions des composants logiciels logiques. Leurs interfaces.
> * La petite étiquette en forme de classeur indique que c'est un composant.
> * Un composant peut être composé. Les composants communiquement via des ports. Ils ont des interfaces où ils ***provident*** (○) et d'autres ils ***requierent*** ($($).
> * Avec le diagramme de déploiement, reflète le **plus** une représentation architecturale.
### 2.7. Diagramme de déploiement

> Jsp on a rien dit là-dessus.

> * Chaque parallélépipède est un noeud, un **environnement d'exécution**.
> * Des fichiers war, jar avec une fichier de configuration xml, sont exécutés dans un environnement d'exécution *Catalina Servlet Container* -> Ce Servlet tourne sur un *"JSP Server" Tomcat 7* -> Et ce Server lui-même tourne sur un device physique de type *Sun Fire X4150 Server*.
> * Les tables se trouvent dans un système de DB *Oracle 10g*. ce dernier tourne sur un device physique *Sun SPARC Server*.
> * Il y a ensuite un noeud qui montre la communication entre les deux, et comment ce dernier est réalisé (typiquement ici par TCP/IP).
> * Évidemment, est totalement et purement **une représentation architecturale** à 3000%.
### 2.8. Composite Structure Diagram
> * Extrêmement détaillé.
> * Extrêmement exotique.
> * Extrêmement pas important.
### 2.9. Use Case Diagram
#### 2.9.1. Business Use Case

#### 2.9.2. System Use Case

> * Un **Actor** est toute entité (humain, un autre système, du matériel, un chien) qui agit **directement** avec le système (sans intermédiaire). *++Ex:++* Si tu dois appelé la secrétaire pour qu'elle t'ajoute dans un système, c'est la secrétaire qui est Actor, pas toi.
> * Lien entre l'acteur est le système indique que ce dernier **intervient** avec le système. Pas plus de précision sur la nature de cette intervention (utilisation, réception, ...).
> * *"Include"* : Quelque chose qui s'ajoute et sera obligatoirement utilisé lors de l'utilisation de la fonctionnalité de base (je crois). *++Ex:++* Ici on **doit** passer par le "Payement" lors du processus de "Checkout", c'est obligatoire !
> * *"Extend"* : Quelque chose qui s'ajouter à la fonctionnalité de base, mais qui n'est pas nécessairement utilisé. *++Ex:++* Ici on **peut** demander "l'aide" lors du "Checkout", mais c'est **pas** obligatoire !
## 3. Semaine 3 (Chapitre 2 - ADL et UML / Chapitre 3 - SysML)
### 3.1. Activity Diagram

> * Représente un Workflow (un processus métier).
> * Transition = simple flèche orientée indiquant l'ordre des tâches à réaliser.
> * Possibilité d'embranchements différents selon tests/prédicats (n'est pas limité à des tests binaires, peut être type switch).
> * Possibilité d'embranchements et joinements ***concurrents*** permettant d'indiquer la réalisation en concurence de plusieurs tâches.
> * Peut être utilisé pour la **conception architecturale** !
### 3.2. State chart Diagram

> * Diagramme d'état de transition = automate d'état fini : on connaît !
> * Décrire le cycle de vie d'une entité (peut être un objet, peut être tout le système).
> * On veut faire un diagramme d'état de transition sur les entités pour lesquelles le changement d'état impact le système = En gros où le changement d'état de l'entité est important :
> * Genre retrait d'argent d'un compte bancaire = **Important** (on peut rester au vert, passer au rouge, avoir son compte bloqué, ...).
> * Genre mouvement d'un objet cube dans un jeux-vidéo = **Pas important** (ça impacte rien de ouf).
> * Chaque transition doit être étiquetté.
> * État composite = État qui compose d'autres états.
> * Exemple ici, c'est une machine à laver. Mais il y a un problème : imagineons on sorte de l'*état composite* car on a ouvert la porte de la machine involontairement. Quand on va refermer la porte, ça va revenir dans l'*état composite* et donc reprendre le programme de lavage **depuis le début** même si on était à **2 minutes de la fin**. Pour ça, on rajoute un H pour dire qu'on doit retenir l'état dans lequel on était avant de sortir de l'*état composite* (là il est pas sur l'exemple, et j'ai pas vraiment compris où il faut mettre ce H, mais il faut en mettre un).
> * Peut être utilisé pour la **conception architecturale** dans le cas où on ne rentre pas trop dans les détails. Cela dépend de ce qu'on est en train de représenter.
### 3.3. Interaction Diagrams
#### 3.3.1. Sequence

> * Se fait entre des classes.
> * Se lit de haut en bas en séquence.
> * Donne la séquence des interactions dans le temps.
> * ***ref*** = Faire référence à un autre diagramme de séquence si on doit y passer, plutôt que de le redécrire entièrement (plus rapide).
> * Est utile pour la **conception architecturale** si pas trop détaillé.
#### 3.3.2. Communication

> * Représente la même chose. La différence est que pour la séquence, on suit les flèches pour dérouler l'ordre des interactions : Ici, on doit suivre la numérotation des interactions.
> * Mais c'est **normal**, ce diagramme n'a pas exactement le même objectif. Ici, on veut d'un seul coup d'oeil pouvoir observer toutes les interactions différentes entre différentes entités, alors que celui de séquence souhaite montrer (spécifiquement !) l'**ordre** des interactions.
> * ***:Order*** = Représente que c'est un objet (une instance) de la classe *Order*.
> * Est utile pour la **conception architecturale** si pas trop détaillé.
### 3.4. What is SysML ?
* C'est un general-purpose **graphical modeling** language qui a pour objectif de : Spécifier, Analyser, Désigner et Vérifier des systèmes complexes, tels que :
* Hardware;
* Software;
* Information;
* Personnel;
* Procedures;
* Facilities.
* SysML n'est **pas** une méthodologie ou un outil ! Il est indépendant de toutes méthodologies ou outils !
* Truc de niche pas très connu en soit.
### 3.5. Maybe useful
* [**[PDF] - SysML : un langage pour la modélisation des systèmes.**](https://eduscol.education.fr/sti/sites/eduscol.education.fr.sti/files/ressources/pedagogiques/6369/6369-sysml-un-langage-pour-la-modelisation-des-systemes-ensps.pdf)
## 4. Semaine 4 (Chapitre 3 - SysML / Chapitre 4 - Data Flow Diagram)
### 4.1. Utilités des diagrams SysML

### 4.2. Electric Kettle Example
> **À Noter : n'est pas une bonne pratique d'avoir le même niveau de détails sur tous les diagrams.**
#### 4.2.1. Use Case

> * L'Utilisateur est le seul Actor **humain** dans ce diagram.
> * Mais l'Eau et l'Électricité sont **aussi** des Actors de ce Use Case.
> * Dans les Use Cases on ne peut pas exprimer les dépendances. Ici, typiquement, il y a un conflit entre l'arrêt manuel (***"extend"***) et l'arrêt automatique (***"include"***).
> * Or, si on arrête manuellement, l'arrêt automatique n'a pas lieu d'être. Mais bon, c'est comme ça.
#### 4.2.2. Requirement

> * Le besoin **nominal** (principal) est l'arrêt automatique du chauffage de la bouilloire (Via le "Contrôle de la température").
> * Or, un fonctionnement **dérivé** (secondaire, également possible) est l'arrêt manuel du chauffage.
#### 4.2.3. BDD (context)

> * Définis le système de son environnement : Éléments matériels et humain interagissant avec lui.
#### 4.2.4. BDD (system)

> * BDD du system lui-même ! C'est-à-dire de la bouilloire électrique directement : quels composants sont nécessaires au fonctionnement de cette dernière.
#### 4.2.5. IBD

> * Ressemble beaucoup à un diagramme de composant en UML.
> * Mais en SysML on a également les ports de flux comme sur cet exemple.
#### 4.2.6. Sequence

> * Montre un scénario **nominal** d'utilisation de la bouilloire par un utilisateur.
#### 4.2.7. Machine d'état

> * Machine d'état de la bouilloire. Ce dernier n'est pas très intéressant étant donné la complexité des états. Néanmoins, les "actionnages" peuvent être intéressants.
### 4.3. Clock Radio Example
Bref, c'est un autre exemple quoi. Il est bien aussi.
> **Voir : Chapitre 03 - Depuis Slide 40.**
### 4.4. Data Flow Diagram
```java=
// TODO
```
## 5. Semaine 5 (Chapitre 5 - Style architecturaux)
### 5.1. Style Architecturale
Ensemble de règles de base (de choix) à suivre qui définissent la manière dont les composants parlent ensemble, comment ils sont déployées physiquement, ... . Généralement définis quelque chose qui représente un besoin récurrent et qui possède donc des invariants.
> Typiquement lorsqu'on eu besoin d'une logique de communication entre client et server, on a développé cette architecture qui a ensuite été réutilisée, et qui est donc commune, à toutes les solutions qui existe (Java, Php, Python, ...).
> Souvent on invente donc pas un style, mais ce dernier émerge de l'expérience : on se rend compte qu'il serait utile de définir tel ou tel concept comme un style architectural.
> * Une application n'est pas nécessairement d'un seul style architectural. Elle peut en avoir plusieurs car il n'y a pas de taxonomie universelle, cela dépend ce que l'on veut étudier.
> * Peut avoir même application avec pleins de style architecturaux différents : Les styles ne sont pas mutuellement exclusifs, ils s'ajoutent !
### 5.2. Program/Subroutines Architecture

> * Simplement la logique de base d'un `Main` représentant le Program principal, puis il y a des fonctions représentant les modules.
> * Les appels aux fonctions/procédures représentent les connecteurs.
### 5.3. Object Oriented Architecture

> Très similaire au Program/Subroutines vu avant, à l'exception que :
> * Les composants sont des objets qui possèdent des états.
> * Ici c'est pas spaguettis.
### 5.4. Layered Architecture

> * La logique applicative est décomposée en plusieurs couches. Chaque couche est abstraite, pas besoin de connaître le reste (ce qui la compose).
> * Une couche apporte des services à la couche du dessus, et utilise les services de la couche du dessous.

> Différentes possibilités sur la façon de call :
> 1. À Gauche => ***"Stricte"***.
> 2. À Droite => ***"Non-Stricte"***.
### 5.5. Sequential Architecture

> On connaît : simplement les programs sont exécutés les uns après les autres jusqu'à complétion.
### 5.6. Pipe/Filters Architecture

> * Souvent permet et est utilisé pour filtrer des données à l'entrée et en récupérer le résultat du filtrage à la sortie.
> * Il n'y a pas d'interactions ni de véritables communications entre les composants (à l'exception que les données de sortie de l'un sont les données d'entrées de l'autre).
> Les avantages :
> 1. C'est que du coup c'est parallélisable (au niveau des composants).
> 2. La logique est modulable, à chaque composant on peut faire quelque chose différent l'un après l'autre (pour une utilisation procédurale : 1 -> 2 -> 3 -> ...).
> 3. Donc du coup, très bon réutilisabilité en résumé.
>
> Finalement, en gros, c'est ce qu'on a fait avec les `Streams` avec Bilat.
### 5.7. Mobile code Architecture
* **Code-on-demand :** Genre ce qu'on a vu en Android avec Aisha : Quand on est offline on a un certain affichage, et lorsqu'on a un accès internet, on peut finalement se synchroniser et updater l'affichage.
* **Remote execution/evaluation :** Genre la fenêtre WebGL qui est intégrée sur la page web. C'est pas le site qui génère cette fenêtre de lui-même : on dit au WebGL quoi faire et on lui demande de nous retourner un canevas, puis l'incorpore à notre page web.
### 5.8. Blackboard Architecture


> ***Slide 45 à 49, à voir.***
### 5.9. Event-based Architecture

> * Des composants peuvent s'échanger (envoyer ou recevoir) des évènements sur un bus commun. Il n'y a autrement pas d'autres communications.
> * On n'envoit **pas** des données, ni des **calls**. En revanche, tout ceci pourraît packagé directement dans l'évènement.
> * Finalement, c'est ce qu'on avait fait en ***Qt C++***.
> * À l'aide d'un typage d'évènements, un composant peut décider de ne s'abonner uniquement à certains types et d'ignorer les autres.
> * Les composants peuvent avoir différents rôles.
> Grand avantage : permet d'éviter de devoir faire du polling constant et incessant (revérifiant périodiquement) pour détecter le changement d'une valeur, mais être **mis au courant** lorsque la valeur a changé.
## 6. Semaine 6 (Chapitre 6 - Architecture of Distributed Systems)
```java=
// TODO
```
## 7. Semaine 7 (Chapitre 7 - Aspects Qualité - Disponibilité)
### 7.1. Disponibility
#### 7.1.1. Tactics for Disponibility
++**Tactics on "fault detection"**++
* Ping/echo
* Asynchronous request/response message between nodes
* Echo prove node availability
* Timeout
- Monitor
* Component responsible for the health of others
* Detects failure or congestion
* Uses other tactics to check other components
* Heartbeats
* Self-test
* Heartbeat
* Periodic message between monitor and a monitored process
* Example : reset watchdog timer to avoid expiring
* Heartbeat message can be integrated within other messages
* Scalability
* Similar to ping/echo put different initiation
- Time stamp
* Tactic used to detect incorrect sequence of events
* Events can be stamped by time of occurrence
* Sequence of number can also be used
* Events generations (Games)
* Sanity checking
* Checking the validity or correctness of component output
* This Tactic requires
* Knowledge of component design
* Knowledge of component state
* Knowledge of the nature of output
* ...
* Mainly used for checking Interfaces
- Condition monitoring
* Checking conditions in a device or process
* Validating assumptions
* Example : checksums
* Condition checking monitor must be simple and introduces no faults
* Voting
* Multiples process working on same inputs
* Output are checked by a voting component
* Example : Triple Modular Redundancy
* Depends on Voting logic
* Implementation
* Replication (clones)
* Functional redundancy (same function, several designs)
* Analytic redundancy (several specifications for the same goal)
- Exception detection
* Detection of system condition that alters normal execution
* Examples
* System exceptions (division by zero)
* Parameter fense (pattern after variable-length parameters)
* Parameter typing (type-length-value messages – subclasses)
* Timeout : detecting failure according to time constraints
* Self-test
* Component running procedures that controls itself
* Procedure can be auto-initiated or activated by monitor
* Can be based on previous techniques for checking (checksum)
++**Tactics on "recovery-preparation & repair"**++
* Active redundancy (hot spare)
* All nodes receive and process identical inputs
* All nodes are supposed to be in the same state
* One response is considered, others are discarded
* Recovery is a fact of switching (milliseconds)
* Requires synchronization
- Passive redundancy (warm spare)
* Only one node receive and process inputs
* Active process is responsible for updating redundant nodes
* Compromise : computation - availability
* Spare (cold spares)
* Redundant spares remain out of service
* In case of failure, power-on-reset procedure
* More adaptable to high-reliability than high-availability
- Exception handling
* Handling of detected exception
* Depends on languages, technologies, ...
* Examples
* ShutDown
* Error code output
* Repeat processing
* Identifying causes and correction
* Rollback
* Rollback line : last known good state
* How to store rollbacks ?
* One node
* External node
* Combined with redundancy
- Software upgrade
* In-service upgrade of executable
* Procedural programming : function patch
* OO programming : class patch
* Hitless In-Service Software Upgrade (ISSU)
* Retry
* Fault is transient
* Retrying can solve the problem
* Example
* Transmission errors
* Must define a number of retries
- Ignore faulty behavior
* Ignoring messages from particular sources
* Suspicious sources
* Non-significant sources
* Example
* Blacklist
* Degradation
* Maintaining critical functions – dropping others
* Faults or failure components must affect only part of the system
* No global failure
- Reconfiguration
* Changing configuration and coordination
* Reassigning responsibilities to resources left functioning
* Maintaining as much function as possible
++**Tactics on "recovery-reintroduction"**++
* Shadow
* A previously failed component may be run in "shadow mode" for a short time to make sure that it mimics the behavior of the working components before restoring it to service
* Useful for failure-components / in-service upgrade components
* Progressive correctness – repopulation
- State synchronization
* The passive and active redundancy tactics require the component being restored to have its state upgraded before its return to service.
* The updating approach will depend on the downtime that can be sustained, the size of the update, and the number of messages required for the update.
* A single message containing the state is preferable, if possible. Incremental state upgrades, with periods of service between increments, lead to complicated software.
* Escalating restart
* Recovering by varying the granularity of components
* Many restarting modes or levels
* Level 0 : kill all failure threads – reinitializing only data
* Level 1 : reinitializing unprotected memory
* Level 2 : reinitializing all memories
* Level 3 : reloading all processes
* Maintaining safety-critical process , reparation process
- Non-stop forwarding
* Continue forwarding (processing) after partial failure
* Routing design
* Example
* Control plane
* Data plane
* Forwarding packets with known routes while routing information is recovered
++**Tactics on "fault prevention"**++
* Removal from service
* This tactic removes a component of the system from operation to undergo some activities to prevent anticipated failures.
* One example is rebooting a component to prevent memory leaks from causing a failure.
* If this removal from service is automatic, an architectural strategy can be designed to support it.
* If it is manual, the system must be designed to support it
- Transactions
* A transaction is the bundling of several sequential steps such that the entire bundle can be undone at once.
* Transactions are used to prevent any data from being affected if one step in a process fails and also to prevent collisions among several simultaneous threads accessing the same data
* ACID : Atomic Consistent Isolated Durable
* Predictive model
* Predictive model combined with monitor
* Detecting likely future failure
* Message queue
* Statistics for process
* Service rate
* Scale
- Exception prevention
* Smart pointers
* Wrappers
* Semaphores
* To avoid exceptions to occur
* Increase competence set
* Involve exception within the scope-competence of process
* Transform an exception to a normal scenario
* Predictable failures
## 8. Semaine 8 (Chapitre 8 - Modifiabilité)
### 8.1. Premières observations
La plupart du coût d'un software typique se produit après sa sortie initiale :
* Maintenir et améliorer un software pour gérer des problèmes ou des nouvelles features à ajouter peu prendre bien plus de temps que le développement initial de l'app :
* Peut être nécessaire d'ajouter du code qui ne s'adapte pas avec le code déjà existant.
* 60%-80% du travail d'un software engineer est à la maintenance :
* Une petite partie consiste à fix des bugs.
* La majorité consiste a add des news features.
* Les changements ne sont pas des exceptions, mais toujours là. On va forcément y passer à un moment donné :
* Pour add des new features ou en retirer des anciennes.
* Fix des bugs, améliorer la qualité (sécurité, performance, ...).
* Passer à de news technos.
* Ajouter de l'interopérabilité avec d'autres systèmes.
### 8.2. Importance de la modifiabilité
* En gros, tout software est amené à **devoir** évoluer, car sinon il deviendra de plus en plus inutile.
* Et si on ne prend pas les précautions nécessaires **en amont** il est plus difficile, plus tard, d'apporter ces améliorations pour faire évoluer le software.
- Un software a forcément une deadline où il ne sera plus "viable", mais en prenant les précautions nécessaires et en s'y préparant, on peut prolonger la vie de l'application sans trop de difficultés et sans ***énormément*** de coût inutile supplémentaire.
* Il ne s'agit pas **que** de corriger des bugs, mais aussi de :
* Prévenir des problèmes future (avec des implémentations adaptées)
* Adapter l'environnement
* Améliorer les qualités de système "constamment"
### 8.3. Analyse de la modifiabilité
* La question centrale est qu'elle est le coût et le risque de devoir effectuer des changements :
* On ne peut pas se préparer à tous les types de changements en amont (évidemment).
* C'est pourquoi l'architecte doit méticuleusement prévoir les changements qui ont le plus de chances de voir le jour, et préparer l'architecture pour les supporter et les accueillir.
* Deux types de coûts :
1. Le coût de l'implémentation du/des mécanisme(s) rendant le système plus facilement modifable (donc ce qui est fait en amont).
2. Le coût des modifications (le jour où elles sont réalisées) utilisant le/les mécanisme(s) préalablement préparé.
++**Exemples**++
1. **Cas 1** : Pas de mécanismes, quand un changement doit être effectué le code source doit être adapté pour l'implémenter :
* Le coût du changement = le coût d'adapter le code source + les tests. Aucun mécanisme n'a été préparé, donc son coût de préparation n'existe pas.
2. **Cas 2** : Un mécanisme a été préparé pour généré automatiquement le code source d'une UI avec une simple description de à quoi elle doit ressembler.
* Le coût du changement = le coût de création de ce mécanisme (le générateur) + le coût de préparation d'une description d'UI, le coût de génération de l'UI avec l'outil et les tests à la fin.
* **->** On voit donc que, bien que le coût en amont soit plus élevé, cela peut être intéressant d'avoir des mécanismes (outils) existants pour réaliser des tâches plus vite. Dans l'exemple 2, on peut générer des UI super simplement et rapidement.
### 8.4. Modifiability General Scenario
* Source : La source qui "trigger" le stimulus (le changement).
* Stimulus : Le changement, l'événement qui va améliorer le tout.
* Artifiact : La portion du système qui va être affecté par ce changement.
* Environment : Le contexte dans lequel le stimulus est trigger.
* Response : La réponse du système à l'application du changement.
* Response measure : Une manière d'assesser la "réponse".
++**Exemple**++
<center><img src="https://hackmd.io/_uploads/HyRxKVsY5.png" width="60%"></center>
### 8.5. Tactics for Modifiability
**++Parameters++**
* Size of a module : La taille d'un module est souvent relié à la probabilité qu'un changement affecte ce module ou la complexité de réaliser un changement dans ce module.
* Coupling : Réduire le "coupling" entre deux modules permet de réduire le coût "prévu" qu'une modification sur un module affecte également d'autres modules.
* Cohesion : Réduire le nombre de responsabilités par module. Au mieux, un module ne devrait avoir qu'une seule responsabilité (tâche).
* Binding time of change : Le moment où les changements sont réalisé dans le "life cycle" du système. Le plus tard et généralement le meilleur !
* Cela implique que l'architecture a été équipée pour accueillir des changements "tard" dans le "life cycle", ex: temps d'exécution.
**++What ?++**
* Tactics sur la modifiabilité ont pour objectif de controller la complexité d'effectuer des changements, le temps et le coût pour les implémenter, les tester et les déployer.
* Pour se faire, les Tactics se basent sur le "tweakage" des paramètres établis ci-dessus.
<center><img src="https://hackmd.io/_uploads/HJ2QkHsFq.png" width="50%"></center>
#### 8.5.1. Tactics on "size of a module"
* Split module
* If the module to modify is large, the modification cost will likely be high.
* Refining the module into several smaller modules should reduce the average cost of future changes
* The ripple effect from a change is the necessity of making changes to modules not directly affected by the initial change.
* For instance, if module A is changed to accomplish a particular modification, then module B is changed only because of the change to module A. B has to be modified because it depends, in some sense, on A.
* Prevention of the ripple effect by reducing the size of modules
* Hide information: it is the decomposition of the responsibilities for a module into smaller pieces and choosing which information to make private and which to make public
* This is the oldest technique for preventing changes from propagating. It is strongly related to "anticipate expected changes" because it uses those changes as the basis for decomposition.
#### 8.5.2. Tactics on "coupling"
* Encapsulate: To introduce an explicit interface to a module (API)
* Perhaps the most common modifiability tactic (information hiding, getter, setter,...)
* Use intermediary: To break dependency between modules
* Architectural style (MVC..), usage of patterns (Facade, Bridge, Proxy,..)
* For exemple a publish-subscrib architecture decouples producers from consumers
* Restrict dependency: To restrict a module’s visibility
* For exemple in a strictly layered architecture a module is only allowed to use the next lower layer (architectural restriction)
* Refactor: To avoid duplicated codes
* When two modules are affected by the same change because they are (at least partial)
* By co-locating common responsibilities that is, making them submodules of the same parent module the architect can reduce coupling
* Abstract common services
* Providing common services through specialised modules is usually viewed as supporting re-use. This is correct, but abstracting common services also supports modifiability
* If common services have been abstracted, modifications to them will need to be made only once rather than in each module where the services are used
* It is also a way to prevent ripple effect
#### 8.5.3. Tactics on "cohesion"
* Increase cohesion
* To move responsibilities from one module to another or to a new one
* To reduce the likelihood of side effect affecting other responsibilities
* Increase semantic coherence.
* If the responsibilities A and B in a module do not serve the same purpose, they should be placed in different modules
* By creating a new module or by moving a responsibility to an existing module
* A way to identify responsibilities to be moved
* To anticipate expected changes
* Considering the set of envisioned changes provides a way to evaluate a particular assignment of responsibilities
* Assigning module’s responsibility based on expected changes will increase the cohesion regarding changes, thus prevent the ripple effect
* Drawback: it is not possible to anticipate all changes
#### 8.5.4. Tactics on "Binding time of change"
* Defer binding
* Because the work of people is almost always more expensive than the work of computers, lets the computers handle a change as much as possible
* for exemple by parametrising the applications
* We want to bind as late as possible, a long as the mechanism that allow it is cost-effective
* Tactics to bind values at compile time includes
* Component replacement (for example in a build script or makefile or patterns)
* Compile-time parametrisation (constants,...)
* Aspects
* Tactics to bind values at startup time includes
* Configuration files
* Tactics to bind values at runtime includes
* Runtime registration
* Dynamic lookup
* Polymorphism
* Interpreted parameters
* Plug-ins
### 8.6. En bref
* La modifiabilité se charge des changements ainsi que du coût en temps et en argent d'effectuer ces changements.
* Les changements peuvent être réalisés par des devs, des installers ou des end users :
* Le système peut être préparé pour des changements :
* C'est un "Must" si ces changements ne sont pas fait par des devs
* Il existe un coût à cette "préparation" du système à accueillir des changements.
- Les Tactics pour réduire le coût de réalisation de changements inclues : réduire la taille de module, agrandir la cohésion, réduire le "couplage" et déférrer le "binding time" de changements (?)
- Réduire le coupling est la façon la plus standard de réduire le coût du changement.
- Agrandir la cohésion peut être réaliser par des changements anticipé.
- Déférrer le "binding" time de changements a pour objectif de faire que les changements ne sont pas réaliser au moment du "développement" mais le plus tard possible (ex: à l'exécution).
- Réduire la taille du module est une bonne façon d'éviter le "ripple effect" (*"A ripple effect occurs when an initial disturbance to a system propagates outward to disturb an increasingly larger portion of the system, like ripples expanding across the water when an object is dropped into it."*).
<center><img src="https://hackmd.io/_uploads/HkZSbSsKq.png" width="75%"></center>
## 9. Semaine 9 (Chapitre 9 - Sécurité)
### 9.1. Premières observations
* La sécurité est une mesure la capacité du système à protéger ces données et services aux accès non-authorisées tout en fournissant toujours un accès efficace aux personnes/systèmes authorisés.
- Les trois grands pilliers de la sécurité (CIA) :
* Confidentiality : Les données ou services ne peuvent pas être visualisés par des personnes non-authorisées.
* Integrity : Les données ou services ne peuvent pas être modifiés ou manipulés par des personnes non-authorisées.
* Availability : Les données ou services sont néanmoins accessibles aux personnes authorisées sans les gêner.
* Pour supporter les pilliers CIA :
* Authentication : Vérifier l'identité des parties qui prennent part à la transaction et vérifier si ils sont véritablement ceux qu'ils "claiment" être.
* Technos : password, one-time passwords, certificats digitals, ... .
* Non-repudiation : Guarantie que l'iniateur d'une transaction ne peut pas nier avoir initier la transaction et qu'un participant à la transaction ne peut pas nier y avoir pris part.
* Authorisation : S'assurer que les users authentifiés ont le droit d'accéder et/ou modifier les datas ou services.
- Un système est considéré secure s'il peut détecter, résiter, réagir et le cas échéant se rétablir avec succès rapidement après une attaque.
### 9.2. Security General Scenario
* Source : L'entité qui souhaite casser les pilliers CIA.
* Stimulus : La tentative de cassage du CIA (l'attaque elle-même).
* Artifiact : Ce sur quoi l'attaque est dirigée.
* Environment : Le situation dans laquelle se trouve le système durant l'attaque (on/offline, operational, ...).
* Response : La réponse du système pour assurer le CIA.
* Response measure : Mesure des dégats causé par l'attaque et l'efficacité de la réponse.
<center><img src="https://hackmd.io/_uploads/B1RlLHjYc.png" width="75%"></center>
### 9.3. Tactics for Security
**++Parameters++**
* Detect : Détecter les attaques avant qu'elles ne se produisent et les empêcher.
* Resist : Résister aux attaques lorsqu'elles ont pû passer et sont en train de se produire.
* React : Réagir aux attaques en cours d'agissement.
* Recover : Se rétablir après que des attaques est réussi à passer.
**++What ?++**
* Les Tactics de sécurité dans le monde des softwares sont très inspirés des Tactics de sécurité et de protection physique :
* Des points de contrôles avec des portes gardées, des badges, dse signatures, ... .
* Pour se faire, les Tactics se basent sur le “tweakage” des paramètres établis ci-dessus.
<center><img src="https://hackmd.io/_uploads/HkqJtSsYq.png" width="50%"></center>
#### 9.3.1. Tactics on "Detection"
* Detect intrusion : basé sur la comparaison de trafic réseau ou requête de service ou pattern de ressources à un set de signatures/patterns malicieux déjà connus.
* Detect service denial : basé sur la comparaison de patterns ou signatures de trafic réseaux à des profils historique connus pour des attaques de denial-of-services (typiquemnt DDoS).
* Verify message integrity : basé sur la vérification des caractéristiques du messagers. Que celui-ci n'a pas changé (checksum, hash, signature, ...).
* Detect message delay : En gros si le message met trop de temps à transiter d'un user A à un user B, alors cela peut signifier que quelque chose de malicieux est en train de se passer (typiquement une Man-in-the-Middle attack).
#### 9.3.2. Tactics on "Resistance"
* Identifier et authentifier les acteurs :
* Identifier les transactions en sachant qui sont les sources d'inputs : Un user ID, des codes d'accès, des adresses IPs, protocoles, ports, ... .
* Authentifier pour s'assurer de l'identité des acteurs : Mot de passes, signatures digitales, ... .
- Contrôle d'accès :
* Quelqu'un n'accède au système qu'avec une de ces Tactics : acteurs authorisés, accès limité et "exposure" limité.
* Authosiation : s'assurer que seul les acteurs **authentifiés** authorisés peuvent accéder aux datas/services.
* Accès limités : des "portes vérouillés" ! Typiquement des ports fermés, des protcoles désactivées, des pares-feux, proxy, DMZ, ... .
* "Exposure" limité : Pour limiter le spread d'une attaque, on évite de donner trop de pouvoir de supervisions (seulement ce dont ils ont besoin) : Tactic passive.
* Chiffrement :
* Assure la confidentialité : Ne guarantit pas que personne ne va pouvoir mettre la main sur cette donnée. Mais vu qu'elle est "chiffrée" bah elle est illisible à ceux qui n'y ont pas le droit d'accès (donc osef).
* Deux types d'encryption :
* Symmetric : Les deux parties partagent une même clé de chiffrement.
* Assymetric : Chaque partie à deux types de clés (public/privé).
- Entités séparées :
* On isole les différentes parties du système qui n'ont pas à communiquer ensemble ou qui n'ont pas à être "gérées" de la même façon.
* Ex: conserver des données non-sensibles et sensibles dans des endroits séparés.
* isolation peut être physique (en isolant de toute conection à internet par exemple, une machine dans l'infrastructure non-reliée) ou logic (firewall, ports lockés, DMZ, ...).
* Change les settings par défaut :
* Souvent les systèmes sont livrés avec des paramètres par défaut qui ne sont pas les plus sécurisés. Une simple Tactic consiste à les changer ou forcer les users à le faire.
#### 9.3.3. Tactics on "Reaction"
* Révoquer des accès :
* Si on pense qu'une attaque est en cours, alors les accès peuvent être sévèrement (ou entièrement) limitée pour certains voir pour tous les users ou systèmes (on pense au cas où une compte admin s'est fait piraté).
- Locker les ordinateurs :
* Des tentatives répétées de logins ratées peuvent indiquer une attaque potentielle. Il est possible peut interdire l'accès au système pour les ordinateurs sur lesquels une attaque de ce genre est en cours.
* Informer les actors :
* Informer les actors qui peuvent faire quelque chose en cas d'attaque pour qu'ils utilisent leur droits et leur big brains pour faire quelque chose.
#### 9.3.4. Tactics on "Recovering"
Au final, ces techniques sont très similaire à celles utiliser pour le "recovering" à des fautes (voir Availibity). En effet, l'objectif consiste maintenant principalement à restorer les services et les datas affectés par l'attaque dans leur état correct (quand l'attaque n'avait pas encore eu lieu).
Donc ces Tactics consistent en :
* Redundancy (passive ou active)
* Spare
* Exception handling
* Rollback
* Software upgrade
* Reconfiguration
* Shadow
* State synchronization
* Escalting restard
* Non-stop forwarding
### 9.4. En bref
* Les attaques sont caractérisées par une volontée de casser un/des pillier(s) du CIA.
* Identifier, authentifier et authoriser différents acteurs sont des Tactics pour déterminer quels users ou systèmes ont accès à quel type de droits dans le système.
* Il y a des Tactics pour détecter, limiter le spread, réagir ou recovering d'une attaque.
* Recover d'une attaque consiste en grande partie aux mêmes Tactics que l'Avaibility.
* Cela consiste principalement à revenir à un état correct du système.
<center><img src="https://hackmd.io/_uploads/rk7NhDoKc.png" width="75%"></center>
## 10. Semaine 10 (Chapitre 10 - Performance - Interopérabilité)
### 10.1. Performance
#### 10.1.1. Premières observations
* Le goal des Tactics des performances est de générer une réponse à un évènement arrivant dans le système dans un temps imparti !
* Les events peuvent être single ou "stream" et sont trigger par une *computation request*
* Cela peut être l'arrivée d'un message dans le système, l'expiration d'un interaval de temps, ... .
* Le système process des events et génère des réponses (c'est son job).
* Les performances Tactics sont là pour contrôler le temps que cela prend pour générer des réponses.
- Après qu'un event arrive, soit le système va processer tout ça ou le processing est bloqué pour une raison ou une autre.
- Généralement c'est pour une des raisons suivantes :
* Resource consumption : CPU, data stores, network communication bandwith, RAM.
* Blocked time : Peut être bloqué à cause de l'utilisation d'une ressource sur laquel il y a une contention (déjà utilisé par un autre process), car la ressource est non-disponible, ou car le résultat dépend d'autres computations non-finies.
* Contention.
* Availability.
* Dependency on other computations.
#### 10.1.2. En bref & Tactics
**++Parameters++**
* Resource Demand : Gérer la demande des ressources.
* Resource Management : Gérer la gestion des ressources.
* Resource Arbitration : Gérer l'ordre/la logique d'accès aux ressources.
**++What ?++**
* Pour se faire, les Tactics se basent sur le “tweakage” des paramètres établis ci-dessus.
==**++Resource Demand++**==
* Réduire la latence, accélérer le temps (et donc améliorer les performances) c'est de réduire les ressoruces nécessaires pour processer un stream d'événement :
* Augmenter l'efficacité de la computation.
* Réduire la computation overhead (les excès de computation, inutiles).
* Réduire la latence c'est aussi de réduire le nombre d'events processer :
* Gérer la fréquence d'events (combien on process en même-temps).
* Contrôler la frequency du sampling (?).
* Controller l'utilisation des ressources :
* Borner le temps d'exécution (?).
* Borner la taille des queues (bah en gros le nombre d'events quoi).
==**++Resource Management++**==
* Introduire de la concurrence : Si les requêtes peuvent être process en parallèle, le temps où on reste "blocked" peut être réduit.
* Maintenir plusieurs copies soit des datas ou des computations. J'imagine d'avoir plusieurs serveurs de process plutôt qu'un seul (?).
* Augmenter les ressources disponibles : Des processeurs plus rapides, plus de processeurs, RAM en plus, réseaux plus rapides, ... tout ça réduit la latence.
==**++Resource Arbitration++**==
* First-in/First-out. Les queues FIFO traitent toutes les requêtes de manières égales et les gèrent ainsi dans leur ordre d'arrivé, simplement.
* Fixed-priority scheduling : Assigne à chaque source qui a fait une requête d'accès ressource un niveau de "priorité", puis gère ainsi les requêtes dans cette ordre.
* Semantic importance.
* Deadline monotic.
* Rate monotic.
* Dynamic priority scheduling :
* Round-Robin (ex: 1000 tasks, 4 procs, dans l'ordre des procs puis modulo).
* Eariest Deadline First : l'event dont la deadline est la plus courte (qui **doit** recevoir sa ressource avant la fin de ce temps ou il se barre).
* Static scheduling : La séquence d'assignation aux ressources sont dterminées "offline".
<center><img src="https://hackmd.io/_uploads/r1SXlOiK9.png" width="75%"></center>
### 10.2. Interopérabilité
#### 10.2.1. Premières observations
* L'interopérabilité est une caractéristique d'un produit ou d'un système, dont les interfaces sont totalement comprises pour fonctionner avec d'autres produits ou systèmes, présents ou futures, soit dans l'implémentation ou l'accès sans aucune restrictions.
* Syntatic interoperability : Si deux systèmes ou plus sont capables de communiquer, ils démontrent une interopérabilité syntactic si ils utilisent des formats de données "spécifiés" et des protocoles de communications.
* Semantic interoperability : Au-dela ! De l'abilité de deux système ou plus à échanger des informations, l'interopérabilité semantic et l'abilité d' **automatiquement** interprété automatiquement l'information échangé de façon correcte et utile afin de produire un résultat utilisable tel que défini par les end users de chaque systèmes.
#### 10.2.2. Interoperability General Scenario
* Source : Un système qui initie une requête pour "intéropérer" avec un autre système.
* Stimulus : Une réquence pour échanger de l'information entre différents systèmes.
* Artifact : Les systèmes qui souhaitent intéropérer.
* Environment : Est-ce que les systèmes souhaitant intéropérer sont découvert au runtime ou avant le runtime (?).
* Response : Une ou plusieurs des possibilités suivantes :
* La requête est (de façon appropriée) rejetée et les entités concernées (users ou systèmes) en sont notifiées.
* La requête est (de façon appropriée) acceptée et de l'information est échangée avec succès.
* La requête est loggé par un ou plusieurs systèmes involved (?).
* Response measure : une ou plus de possibilités suivantes :
* Pourcentage d'information échangée correctement "processée".
* Pourcentage d'information échangée correctement "rejetée".
<center><img src="https://hackmd.io/_uploads/SkD5vuiK9.png" width="75%"></center>
#### 10.2.3. En bref & Tactics
**++Parameters++**
* Locate : ???
* Manage interfaces : ???
**++What ?++**
* Pour se faire, les Tactics se basent sur le “tweakage” des paramètres établis ci-dessus.
==**++Locate++**==
* Discover services :
* Directory Service
* Multiple indirection searching
* Multiple critère de recherches :
* Nom, author, key words
* Domain, Type, Authority
* Semantic attributes
==**++Manage interfaces++**==
* Orchestration :
* Coordiner et manager la séquence d'invocation des services
* Principalement utilisé pour des tâches complexes
* Scripts d'orchestration :
* Workflow Engine
* Mediator design pattern
* ORchestration language (BPEL)
* Tailors interfaces :
* Ajouter ou retirer des "capacités" des interfaces.
* Ajouter des capacités :
* Traduction, buffering, smoothing, ... .
* Retirer des capacités :
* Cacher des fonctionnalités pour des users de non-confiances.
* Design Pattern "Decorator".
<center><img src="https://hackmd.io/_uploads/HkjWKuoY9.png" width="75%"></center>
## 11. Semaine 11 (Chapitre 11 - Usability)
### 11.1. Premières observations
* La préoccupation de la Usability est à quel point il est simple pour le user de réaliser sa tâche désirée et le genre de "user support" le système fourni.
* L'Usability touche à la fois à des aspects architecturaux et non-architecturaux.
* Non-architecturaux : Inclus le fait de rentre l'interface claire et facile a utilisée.
* Ce n'est pas architectural car cela appartient aux détails du design de user interface.
* *"La manière dont les choses sont présentées au user"*
* Architecturaux : L'abilité de pouvoir annuler/undo/redo des opérations ou ré-utiliser des datas entrées précédemment (formulaires) **est** un aspect architecural.
* Ces requirements involve la coopération de multiples élèments.
**++Exemples++**
* Learning system feature : Fournir un *"help"* contextuel -> learning curve.
* Utilisé un système de façon efficace : Pouvoir suspendre une task, performer plusieurs opérations puis reprendre la task.
* Minimiser l'impact d'erreurs : L'user pourrait souhaiter cancel une commande non-correcte (après qu'elle ait été lancé).
* Adapter le système aux besoins users : Le système pourrait automatiquement remplir un champ basé sur une ancienne entrée user.
* Augmenter la confiance et la satisfaction : Donner des feedbacks, des progress bars, ... pour les actions qui prennent du temps typiquement.
**++Important++**
* Il a été montré et compris qu'il y a une relation importante l'usabilité et l'architecture logicielle :
* C'est une des façons les plus "bon marché" et facile d'améliorer la qualité d'un système, ***ou plutôt***, la perception du user de la qualité du système hehehe :wink:
* Le processus normal de développeent détecte les problèmes d'Usability à travers le building de prototype (?) et le **user testing** :
* Or, plus tard le problème est découvert, plus de chance il y a que l'architecture doive être profondément modifiée en conséquence.
* Dans nos scénarios, nous nous concentrons sur des aspects d'Usability ayant un gros impact sur l'architecture :
* Conséquemment, il est important de les avoir **déjà** bien correctement implémentés avant le design de l'architecture, afin qu'ils ne soient pas découverts durant le prototyping, ou pire, le user testing.
### 11.2. Usability General Scenario
* Source : Le end user est toujours la source du stimulus (peu importe qu'il soit un "standard" user ou un user "spécialisé", ...).
* Stimulus : Le fait qu'un end user souhaite utiliser un système de façon efficace, apprendre à utiliser le système, minimiser l'impact d'erreurs, adapté le système et se sentir comfortable à l'utiliser.
* Artifact : Le système ou la portion spécifique du système avec laquelle le user souhaite intéragir.
* Environment : Les user actions avec lesquels il y a des problèmes d'Usability au runtime ou "système configuration" time.
* Response : Le système devrait soit fournir aux users les features dont il a besoin ou anticiper les besoins de l'utilisateur.
* Response measure : Mesurer par task time, nombre d'erreurs, nombre de problèmes résolus, user satisfactions, le gain de connaissance du user, le ratio d'opérations "successful" au nombre total d'oérations, le nombre de temps/datas perdus quand une erreur se produit
<center><img src="https://hackmd.io/_uploads/HJmmktsY9.png" width="75%"></center>
### 11.3. Tactics for Usability
**++Parameters++**
* User Interface : Faciliter l'utilisation et l'expérience utilisateur par l'UI.
* User Initative : Lorsque le système est running, l'Usability est améliorée si le user obtient les feedbacks appropriés sur ce qu'il est en train de se passer et peut faire des décisions du type : cancel, undo/redo, pause/resume et aggregate.
* System Initiative : Détecter ses propres intentions ou les intentions de l'utilisateur.
**++What ?++**
* Pour se faire, les Tactics se basent sur le "tweakage" des paramètres établis ci-dessus.
<center><img src="https://hackmd.io/_uploads/BkwmgtoYc.png" width="50%"></center>
#### 11.3.1. Tactics on "Separate the User Interface"
* Donner à l'utilisateur la possibilité de tester différentes UI.
* La meilleure façon de faire ça et designer le software afin que l'UI puisse facilement être modifiée :
* Ainsi, c'est similaire à la Modifiability, ainsi c'est plus cohérent.
* Souvent La qualité d'attributs sont en conflits l'un l'autre, tels que certains cas de la Testability Vs la Performance. Néanmoins, la Usability, la Modifiablity et la Testability sont souvent complémentaires !
#### 11.3.2. Tactics on "Support User Initative"
* User obtient les feedbacks appropriés sur ce qu'il est en train de se passer.
* User, en fonction des feedbacks, peut décider de réaliser des actions tels : cancel, undo/redo, pause/resume et aggregate.
* Cancel : Le système doit immédiatemment abandonner la commande et le systèem doit retourner à son état "stable" précédant l'exécution de la commande.
* Undo : Le systèem doit maintenir un nombre suffisant d'information à propos des states du système afin qu'un state consistant précédent puisse être restoré sur une requête user le demande.
* Pause/Resume : Souvent utile de fournir des possibilités de pause/resume d'opérations (surtout pour longues opérations).
* Pauser nécessite de libérer temporairement des ressources.
* Aggregate : Lorsqu'une même opération est performé sur pleins d'objets, il peut être utile d'agréger les objets afin de libréer l'utilisateur de devoir relancer manuellement l'opération sur chaque objets individuels (typiquement le unzippage avec 7z).
* Utiliser le "command pattern" peut beaucoup améliorer l'implémentation de toutes les Tactics mentionnées ci-dessus.
#### 11.3.3. Tactics on "Support System Initiative"
* Détecter ses propres intentions ou les intentions de l'utilisateur :
* Maintenir le task model : Le task model est utilisé pour déterminer le context des tasks afin que le système ait une idée de ce que le user est en train d'essayer de réaliser et lui fournir différents types d'assistances.
* Exemple : Auto-complétion, champs pré-remplis basés sur d'anciennes entrées ou correction automatique.
* Maintenir le user model : Cela détermine les connaissances du user vis-à-vis du système, le comportement de l'utilisateur en terme du temps de réponse attendu et autres aspects spcéfiques à un user ou une classe de users.
* Un simple cas de cette Tactic est dans la customisation de l'UI, là où un user peut explicitement modifier le user model du système (dire si il veut des fonctions de beginner ou expert, pour faire plus de trucs).
* Maintain system model : Le système maintien un model explicite de lui-même pour déterminer les comportements attendus du système afin qu'un feedback appropiré puisse être donné à l'utilisateur.
* Progress bar est un exemple simple et typique de cette Tactic.
### 11.4. En bref
* L'objectif de la Usability est donc :
* D'aider le User à apprendre des feature du système, à l'utiliser efficacement et à minimser les impacts d'erreurs.
* Adapter le système selon les besoins users.
* Augmenter la confiance et la satisfactions du user vis-à-vis du système.
* Le support archtectural consiste à supporter à la fois les initatives users et les initatives systèmes :
* Les users initatives sont :
* Cancel, undo/redo, pause/resume et aggregate.
* Design pattern tel qu "command pattern" peuvent grandement aider à la réalisation de ces Tactics.
* Les systèmes iniatives sont :
* Maintain Task Model, Maintain User Model, Maintain System Model.
* ==**L'objectif étant de préduire les comportements du systèmes et les intentions du user.**==
*
<center><img src="https://hackmd.io/_uploads/S1vg9OjKc.png" width="75%"></center>
## 12. Semaine 12 (Chapitre 12 - Testabilité)
### 12.1. Premières observations
* Une part importante du coût de développement de "well-engineered" systèmes concerne le Testing.
* Si un software architect peut réduire les coûts ici, alors les gains seront énormes.
* La facilité avec laquelle le software peut démontrer ses fautes à travers du Testing.
* En particulier, la Testabilité réfère à la probabilité (si système au moins une faute) que le système fail durant le Testing.
* Intuitivement, un système est "Testable" si il montre ces fautes de manière "facile" (rapidement).
* Pour être proprement Testable, il doit être possible de controller l'état interne et les inputs de chaque composants et d'observer leur outputs.
* Et possiblement de manipuler son état interne.
* Testing se fait par pleins de développeurs, testeurs, vérifieurs ou même users, et est la dernière étape des différents parties d'un software "life-cycle".
**++Important++**
* Logging : est une stratégie commune pour addresser la Testability.
* Logger les datas opérationnels produit par le système, afin que durant une failure, les logged datas puissent être analysés et les fautes reproduites.
* Architecuralement cela nécessite des mécanismes d'accès et de log de certains états du système.
* Fonctionnellement, cela peut nécessiter des mécanismes (interne ou externe au système) d'injecter des fautes dans le système afin d'identifier la raison des fautes plus tard.
### 12.2. Testability General Scenario
* Source : La source pourrait être humaine ou un test automatique. Cela peut être un unit tester, un integration tester, un system tester, un acceptance tester ou un end user.
* Stimulus : Sets de tests qui sont executés.
* Artifact : L aprotion de code qui est testé. Cela peut être une unit éde code, un module, un subsystème ou le système entier.
* Environment : Lorsque le test est performé (development time, deployment time, lorsque le système est en cours d'exécution).
* Response : Les résultats observés du test.
* Response measure : Avec quelle facilité le système "a lâché" ses fautes. De manière général, cela mesure "l'effort" à fournir pour trouver une faute en particulier :
* Cela peut inclure : le temps/effort à préparer l'environnement de test, la longueur de la plus grande chaîne de test, la durée du système étant offline, ... .
<center><img src="https://hackmd.io/_uploads/B1SovKjFq.png" width="75%"></center>
### 12.3. Tactics for Testability
**++Parameters++**
* Controlability and observality of system state :
* Limit of complexity in system's design :
**++What ?++**
* Pour se faire, les Tactics se basent sur le "tweakage" des paramètres établis ci-dessus.
<center><img src="https://hackmd.io/_uploads/BkUBlYiK5.png" width="50%"></center>
#### 12.3.1. Tactics on "Control and observe system state"
* Interaces spécialisées : Des interfaces de Testing spécialisées permettent de capturer et/ou de controller des valeurs de variables pour un composant soit à travers un *test harness* ou une exécution normal :
* Getter, setter, reports, reset, verbose mode
* Ces interfaces devraient être clairement identifié et/ou conserver séparément des interfaces pour des fonctionnalités nécessaires, afin de pouvoir être retirer si nécessaire.
- Record/playback : L'état qui a causé la faute est souvent difficle à recréer. Enregistrer l'état lorsqu'il traverse un interface permet de pouvoir rétuiliser le state pour le "re-jouer" et recréer l'erreur.
* Tactic qui se réfère à la fois au capture d'information qui traverse une interface et son utilisation comme input pour plus de Testing.
* Localise state storage : Faciliter le (re-)démarrage d'un subsystème dans un état ***arbitraire*** pour ewffectuer un test.
* Si l'état est "buried" ou distribué c'est plus difficile, voir impossible à faire.
* L'état peut être stored en un fin grain (bit-level) ou coarsed grain (abstraction-level).
- Asbtract data sources : Facilement contrôler les datas inputs.
* Permet de substituer les datas inputs avec des datas de tests provenant de sources dédiées ou même manuellement entrées.
* Sandbox : Correspond au fait d'isoler une instance d'un subsystème du vrai monde afin de permettre à l'expérimentation d'éviter l'inquiétude de devoir undo les conséquences de l'expérimentation.
* Virtualisation (virtual machine) est typiquement une manière de sandboxer.
- Assertions d'exécutable : Assertions sont (généralement) codées à la main et placés aux endroits désirés afin d'indiquer quand et où le programme à un état faulty.
- Pour vérifier que la valeur statisfasse une contrainte choisie.
- Les Assertions sont aussi une manière de "ré-utiliser" (?).
++**Replacement (truc en plus, jsp trop)**++
* All of these tactics add capability or abstraction to the software that (were we not interested in testing) otherwise would not be there.
* There are a number of techniques for replacing one component with a different version of itself. They include the following
* Component replacement, which simply swaps the implementation of a component with a different implementation that (in the case of testability) has features that facilitate testing. Component replacement is often accomplished in a system's build scripts.
* Preprocessor macros that, when activated, expand to state-reporting code or activate probe statements that return or display information, or return control to a testing console.
* Aspects (in aspect-oriented programs) that handle the cross-cutting concern of how state is reported.
#### 12.3.2. Tactics on "Limit Complexity"
* Observation : Les systèmes complexes sont difficiles à tester, car le Testing ne consiste pas juste à faire "fail" le système mais aussi à **trouver** la faute qui cause la failure.
- Limit structural complexity : Les Tactics principales sont :
* Éviter les cycles de dépendances, isoler et encapsuler les dépendances dans des environnements externes et réduires dépendances entre composants :
* Haute cohésion, faible "coupling" et spéparation des préoccupations (voir Modifiability, très similaire).
* Limit non-determinism : La contre-partie du fait de limiter la complexité structurelle est de limiter la complexity comportementale :
* Non-déterminisme est une forme complexe de comportement très pernicieuse (nuisible).
* Cette Tactic consiste à trouver toutes les sources non-déterministes et de les éviter autant que possible.
* Certaines sources de non-déterminisme sont inévitables, par exemple dans des systèmes parallèles ou distribués. C'est pourquoi ce type de systèmes est spécifiquement difficile à distribuer. ==**D'autres Tactics doivent alors utiliser comme le playback !!!**==
### 12.4. En bref
* Assure que le système est facilement testable et a du gain, non pas seulement en termes de coût de testing mais aussi de "reliability" du système.
* Testability est fortement lié à la modifiabilité, réutilisabilité et l'avaibility.
* Certaines Tactics sont similaires.
* Controller et observer est une classe majeur des Tactics de testability.
* Fournir la possibilité d'injecter des fautes, d'enregistrer l'état du système et d'isoler des portions du système du reste du ou de l'environnement, d'abstraire les ressources signifent généralement l'utilisation de *test harness*.
* *Test harnesses* sont des systèmes de softares qui encapsulent des tests de ressources rendant plus facile d'appliquer le test d'infrastructure.
* Les système complexes sont difficiles à tester en raison du large espace d'états dans lequel l'exécution se produit.
* Non-déterministe est une forme particulièrement pérnicieuse (nuisible) de comportement complexe.
* Limiter voir éviter le non-déterminisme est une Tactic pour la Testability.
<center><img src="https://hackmd.io/_uploads/rySt5usY9.png" width="75%"></center>