Sujet NFP121 Cnam Versailles Juillet 2015
Transcription
Sujet NFP121 Cnam Versailles Juillet 2015
CONSERVATOIRE NATIONAL DES ARTS ET METIERS Cnam / Versailles Examen UE – NFP 121 : Programmation avancée Session de Juillet 2015 Le 4 Juillet 2015 Durée : 3 heures Document (s) autorisé(s) : Tout document PAPIERS autorisés Calculatrice : Non Autorisé Téléphone portable, ordinateur : Interdit Le sujet comporte 15 pages (dont celle-ci). Le barème d’évaluation : question 1 : 7 pts ; question 2 : 7 pts ; question 3 : 3 pts Question1 : Patron « DECORATEUR » question 4 : 3 pts (7 points) Le pattern Decorator permet d’ajouter des fonctionnalités à un objet de manière dynamique. L’objet décorateur référence l’objet initial et se substitue à lui, son interface est la même de sorte que la substitution reste transparente vis-à-vis du client. Les Widgets (Window Gadget) sont de petits composants logiciels que l’on retrouve sur les bureaux de PC et qui sont interactifs. Ils proposent habituellement des informations ou des divertissements. Par exemple, certains affichent les cours de la bourse ou des informations météorologiques alors que d'autres permettent de jouer à des jeux vidéo généralement assez basiques L’architecture des classes pour cette question est la suivante (en notation R.Rose/UML) <<abstract>> Widget 1 Calendrier Widget #description ControleursApplications +calculePrix() +afficheDescription() +calculPrix() +afficheDescription() +calculePrix() +afficheDescription() WidgetClassique WidgetAgrandissable WidgetMulticolor DecorateurWidget +calculePrix() +calculePrix() +calculePrix() +calculePrix() +afficheDescription() AfficheurDeFluxRss SurveillanceSystem +calculePrix() +afficheDescription() +calculePrix() +afficheDescription() HorairesTrains +calculePrix() +afficheDescription() BulletinsMeteo JeuxAvances +calculePrix() +afficheDescription() +calculePrix() +afficheDescription() Chaque widget de base (il y en a 3) est représenté par une classe. Une classe Décorateur Widget ayant pour sousclasses les différentes classes des spécificités. La classe abstraite Widget détient l’interface destinée aux clients. Elle a comme sous-classes des widgets de Base ainsi que la classe DecorateurWidget. Cette dernière référence vers une widget. NFP121-examen-Juillet-2015 Cnam/Versailles Travail à faire pour la question 1 Programmez ce diagramme en Java en attribuant un prix et une description à chaque base et option puis testez-le en créant un widget et en affichant sa description et son prix. //Le code source Java définissant la classe abstraite Widget est comme suit. public abstract class Widget { protected String description = ””; public String afficheDescription() { return description; } public abstract double calculePrix(); } 1. Les différentes classes concrètes pour les widgets implantent la méthode calculePrix() qui retourne leurs prix. Le constructeur initialise l’attribut description. 1.1 La classe WidgetClassique : le prix à retourner est 2.99€ et l’initialisation de la description est "Widget classique". public class WidgetClassique extends Widget { //A terminer } 1.2 La classe concrète WidgetMultiColor : le prix à retourner est 3.99€ et l’initialisation de la description est "Widget à colories variables". public class WidgetMultiColor extends Widget { A terminer } 1.3 La classe concrète WidgetAgrandissable le prix à retourner est 5.99€ et l’initialisation de la description est "Widget agrandissable à souhait" public class WidgetAgrandissable extends Widget { A terminer } // La classe DecorateurWidget implante les méthodes calculePrix () et afficheDescription () en déléguant l'appel au composant référencé dans son attribut widget de type Widget. public abstract class DecorateurWidget extends Widget { protected Widget widget; public DecorateurWidget(Widget widget) { this.widget = widget; } @Override // A terminer } NFP121-examen-Juillet-2015 Cnam/Versailles Implantez les méthodes calculPrix() et afficheDescrition dans les différentes classes concrètes en utilisant pour chacune d’elles les éléments suivants : - AfficheurDeFluxRss coute 5.10 € - SurveillanceSystem coûte 3.20 € - BulletinsMétéo coute 2.80 - JeuxAvances coute 1.50 - Calendrier coute 0.30 - ControleursApplications coute 0.40€ - HorairesTrains coute 0.80€ La classe Utilisateur introduit le programme principal. Dans celui-ci, deux widgets sont crées et leurs descriptions et prix sont affichés : public Utilisateur { public static void main(String[] args) { Widget widget1 = new WidgetMultiColor(); // A terminer Widget widget2= new WidgetClassique (); // A terminer } } Terminer ce programme au détail près. Pour info Le résultat s'affichant lors de l’exécution de ce programme est TRES EXACTEMENT le suivant. Première widget: Widget multi Color,, Afficheurs De Flux Rss, JeuxAvances, Contrôleurs d’applications. Calendriers Tarif: 11.290000000000001 Seconde widget: Widget classique, BulletinsMétéo, JeuxAvances, HorairesTrains Tarif: 8.09 NFP121-examen-Juillet-2015 Cnam/Versailles Question2 (7 points) : Patron « Observer » Le pattern Observer permet d’établir un lien entre un sujet et des observateurs de sorte que toute modification du sujet soit notifiée à ses observateurs qui sont mis à jour en conséquence. Dans l’application météo, le sujet concret est l’objet DonneesMeteo. Il notifie les applications d'affichage, qui sont les observateurs, de tout changement de son état interne. L’association avec les observateurs se fait à travers une classe abstraite qui est le sujet et une interface Observateur qui reçoit les notifications. La classe Sujet implante les méthodes pour ajouter et retirer des observateurs ainsi que celle pour notifier les observateurs. La partie du diagramme de classe concernant le sujet est la suivante : Sujet #observateurs +ajoute(observateur) +retire(observateur) +notifie() 0..* <<interface>> Observateur +actualise() DonneesMeteo Les observateurs concrets qui sont widgetMeteo et PluginMeteo implantent l’interface Observateur, ils maintiennent un lien vers leur observateur et implante une méthode actualise () pour mettre à jour leur affichage. Plusieurs applications servent à afficher les données météorologiques qui intéressent un utilisateur, parmi elles, le plug-in météo du navigateur Internet et le widget qui s’affiche sur le bureau. Un objet « données météo » se connecte de manière continue à une station distante afin de mettre à jour ses données. Il doit à chaque modification transmettre les nouvelles données aux applications d'affichage. Nous allons appliquer le pattern Observer aux classes du système qui est présentée de la manière suivante : Sujet +ajoute(observateur) +retire(observateur) +notifie() #observateurs 0..* <<interface>> Observateur +actualise() WidgetMeteo DonneesMeteo 1 #sujet 1 +actualise() PluginMeteo #sujet +actualise() NFP121-examen-Juillet-2015 Cnam/Versailles 2.1 On veut programmer ce diagramme en java. Les données à afficher sont la Température, la vitesse du vent et le taux d’humidité. Le code source de la classe Sujet est donné à la suite. Les observateurs sont gérés à l'aide d'une liste. import java.util. * ; public abstract class Sujet { protected List<Observateur> observateurs = new ArrayList<Observateur>(); public void ajoute(Observateur observateur) { observateur.add(observateur); } public void retire(Observateur observateur) { observateurs.remove(observateur) ; } public void notifie() { for (Observateur observateur : observateurs) Observateur.actualise(); } } L'interface Observateur contient la signature (juste la déclaration) de la méthode actualise (). public interface Observateur { void actualise () ; } NFP121-examen-Juillet-2015 Cnam/Versailles La classe DonneesMeteo stocke les valeurs des mesures météorologiques dans les attributs temperature, vitesseVent et tauxHumidite. Elle implante les accesseurs en lecture et en écriture de ces attributs. Les accesseurs en écriture invoquent la méthode notifie de la classe Sujet afin de notifier les observateurs du changement de la valeur. public class DonneesMeteo extends Sujet { protected Double temperature; protected Double vitesseVent; protected Double tauxHumidite; public Double getTemperature() { return temperature; } public void setTemperature(Double temperature) ( this.temperature = temperature; notifie() ; } public Double getVitesseVent() { return vitesseVent; } public void setVitesseVent(Double vitesseVent) { this.vitesseVent = vitesseVent; notifie(); } public Double getTauxHumidite() return tauxHumidite; } { public void setTauxHumidite(Double tauxHumidite) { this. tauxHumidite = tauxHumidite; notifie ( ); } } Les classes WidgetMeteo et PluginMeteo stockent une référence vers leurs sujets. Elles implantent la méthode actualise qui met à jour les données à afficher et une méthode affiche qui imprime à l’écran les nouvelles données météorologiques. Travail à faire 2.1.1 Merci de proposer le code des deux classes WidgetMeteo et PluginMeteo NFP121-examen-Juillet-2015 Cnam/Versailles 2.1.2 La classe utilisateur introduit le programme principal permettant de tester le fonctionnement du système. Le programme crée un objet DonneesMeteo et les objets d'affichage auxquels il transmet l’objet DonneesMeteo. Quelques données sont ensuite modifiées pour tester le bon fonctionnement du système. Travail à faire Donnez le code de la classe Utilisateur : public class Utilisateur{ public static void main(String[] args) { } } Le résultat d'exécution du programme est comme suit. Le Widget affiche une température de: 24.0, une vitesse de vent de: 10.0 et un taux d'humidité de : 8.2 Le Plugin affiche une température de: 24.0, une vitesse de vent de: 10.0 et un taux d'humidité de : 8.2 Le Widget affiche une température de: 25.0, une vitesse de vent de: 10.0 et un taux d'humidité de : 8.2 Le Plugin affiche une température de: 25.0, une vitesse de vent de: 10.0 et un taux d'humidité de: 8.2 Le Widget affiche une température de: 25.0, une vitesse de vent de: 10.0 et un taux d'humidité de: 7.0 Le Plugin affiche une température de: 25.0, une vitesse de vent de: 10.0 et un taux d'humidité de: 7.0 2.2 On veut remanier notre code pour utilise les classes Java prévues pour la mise en place du pattern Observer. Java supporte la mise en place de code basé sur le pattern Observer grâce à l’interface Observer et la classe Observable. L’interface Observer doit être implantée par les observateurs. Elle dispose d’une méthode update() de la forme : public void update (Observable o, Object arg) (où o est le sujet et arg est un argument optionnel qui peut être passé à la méthode notifyObservers () de la classe Observable. Travail à faire 2.2.1 Remaniez votre code pour utiliser les classes java prévues pour la mise en place du Pattern Observer Les classes PluginMeteo et widgetMeteo sont à modifier pour implanter cette interface. La méthode actualise() sera remplacée par la méthode update() de l’interface observer. Les classes attendues sont : NFP121-examen-Juillet-2015 Cnam/Versailles import java.util.Observable; import java.util.Observer; public class PluginMeteo implements Observer { protected Double temperature; protected Double vitesseVent; protected Double tauxHumidite; public PluginMeteo ( ) { // A TERMINER si nécessaire } public void update(Observable obs, Object arg) { // A TERMINER si nécessaire } public void affiche () { // A TERMINER si nécessaire }} import java.util.Observable; import java.util.Observer; public class WidgetMeteo implements Observer { protected Double temperature; protected Double vitesseVent; protected Double tauxHumidite; public WidgetMeteo() { } public void update(Observable obs, Object arg) { } public void affiche () { } } La classe Observable est la classe de base pour coder le sujet. Toute classe qui veut être observée hérite de cette classe de base. La classe DonneesMeteo doit être une sous-classe de la classe Observable. L'appel de la méthode notifie() est remplacé par les deux appels setChanged et notifyObservers indiquant que l'objet a changé et notifiant tous les observa reçoivent une demande d’exécution de leur méthode update. NFP121-examen-Juillet-2015 Cnam/Versailles import java.util.Observable; public class DonneesMeteo extends Observable { protected Double temperature; protected Double vitesseVent; protected Double tauxHumidite; public Double getTemperature() { // A TERMINER si nécessaire } public void setTemperature(Double temperature) { // A TERMINER si nécessaire } public Double getVitesseVent() { // A TERMINER si nécessaire } public void setVitesseVent(Double vitesseVent) { // A TERMINER si nécessaire } public Double getTauxHumidite() { // A TERMINER si nécessaire } public void setTauxHumidite(Double tauxHumidite) { // A TERMINER si nécessaire }} Enfin modifions le code du programme principal. Utilisez de la méthode addObserver () pour assigner des observateurs au sujet. public class Utilisateur { public static void main(String[] args) { // A TERMINER si nécessaire } } NFP121-examen-Juillet-2015 Cnam/Versailles Question3 (3 points) : Patron « SINGLETON » On veut vérifier le comportement de la méthode getInstance () de la classe SingletonWidgetJeuxAvancesTest. Soit la classe Singleton suivante : package singleton; public class Singleton { private static Singleton instance = null; private Singleton () { } public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } Travail à faire Écrivez, à l’aide de la bibliothèque JUnit version 4, la classe SingletonWidgetJeuxAvancesTest contenant les tests pour vérifier : que la méthode getInstance renvoie bien un objet ; que la méthode getInstance renvoie toujours le même objet ; que la méthode getInstance renvoie bien une instance de Singleton. La classe Singleton SingletonWidgetJeuxAvancesTest doit introduire une méthode de test contenant trois assertions. On rappelle que l’annexe vous donne des indications sur les méthodes assertXxx() NFP121-examen-Juillet-2015 Cnam/Versailles Question4 (3 points) : Interface Graphique Une interface graphique a été développée en Swing et ceci dans le but une connexion à un jeux avancés par le biais d’un widgetJeuxAvancé. package interfaceGraphique; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Date; class IhmConnectWidgetGame implements ActionListener { JButton bouton = new JButton(); JPanel panneau= new JPanel(); public IhmConnectWidgetGame() { panneau.add(bouton); JFrame fenetre = new JFrame(); fenetre.setContentPane(this.panneau); fenetre.pack(); fenetre.setVisible(false); bouton.addActionListener(this); } public void actionPerformed(ActionEvent cnamVersailles){ Date dateDuJour = new Date(); JOptionPane.showConfirmDialog( // A Completer); } public static void main(String[] args) { new BoutonAfficheDate(); } } 4.1 Ce code ne s’affiche pas. Corrigez – le. Faites le afficher après avoir trouvé la ou les erreurs et complétez-le pour qu’il puisse afficher successivement les informations des boutons 1 et 2. Commentaires obligatoires Bouton 1 Un clic sur le bouton « Demande de connexion » donne le bouton suivant : Bouton 2 4-2 - Quelles sont les options possibles du premier argument de la JOptionPane.showConfirmDialog() ? Expliquez ce à quoi il sert. Comment peut-on changer le point d’interrogation en point d’exclamation ? FIN NFP121-examen-Juillet-2015 Cnam/Versailles Annexes java.util Interface Set<E> Type Parameters: E- the type of elements maintained by this set All Superinterfaces: Collection<E>, Iterable<E> All Known Subinterfaces: NavigableSet<E>, SortedSet<E> All Known Implementing Classes: AbstractSet, ConcurrentSkipListSet, CopyOnWriteArraySet, EnumSet, HashSet, JobStateReasons, LinkedHashSet, TreeSet public interface Set<E> extends Collection<E> Method Summary boolean add(E e) Adds the specified element to this set if it is not already present (optional operation). addAll(Collection<? extends E> c) Adds all of the elements in the specified collection to this set if they're not already present (optional operation). void clear() Removes all of the elements from this set (optional operation). boolean boolean contains(Object o) Returns trueif this set contains the specified element. boolean containsAll(Collection<?> c) Returns trueif this set contains all of the elements of the specified collection. boolean equals(Object o) Compares the specified object with this set for equality. int hashCode() Returns the hash code value for this set. boolean isEmpty() Returns trueif this set contains no elements. iterator() Returns an iterator over the elements in this set. Iterator<E> boolean remove(Object o) Removes the specified element from this set if it is present (optional operation). boolean removeAll(Collection<?> c) Removes from this set all of its elements that are contained in the specified collection (optional operation). retainAll(Collection<?> c) Retains only the elements in this set that are contained in the specified collection (optional operation). boolean int size() Returns the number of elements in this set (its cardinality). Object[] toArray() Returns an array containing all of the elements in this set. NFP121-examen-Juillet-2015 Cnam/Versailles <T> T[] toArray(T[] a) Returns an array containing all of the elements in this set; the runtime type of the returned array is that of the specified array. java.lang Interface Iterable<T> Implementing this interface allows an object to be the target of the "foreach" statement. Method Summary Iterator<T> iterator() Returns an iterator over a set of elements of type T. java.util Interface Iterator<E> Method Summary boolean hasNext() Returns trueif the iteration has more elements. E next() Returns the next element in the iteration. void remove() Removes from the underlying collection the last element returned by the iterator (optional operation). java.awt.event Interface ActionListener public interface ActionListener extends EventListener The listener interface for receiving action events. The class that is interested in processing an action event implements this interface, and the object created with that class is registered with a component, using the component's addActionListenermethod. When the action event occurs, that object'sactionPerformed method is invoked. Method Summary void actionPerformed(ActionEvent e) Invoked when an action occurs. org.jdom Class Element partielle java.lang.Object org.jdom.Content org.jdom.Element - 13 - An XML element. Methods allow the user to get and manipulate its child elements and content, directly access the element's textual content, manipulate its attributes, and manage namespaces. Constructor Summary Element(java.lang.String name) Create a new element with the supplied (local) name and no namespace. Method Summary Elemen addContent(java.lang.String str) This adds text content to this element. t Elemen setAttribute(java.lang.String name, java.lang.String value) This sets an attribute value for this element. t - Un Widget est un composant logiciel, son nom provient du mot gadget. .Le mot widget être considéré comme étant la contraction des termes window (fenêtre) et gadget. Il peut désigner : un widget interactif, un petit outil qui permet d'obtenir des informations (météo, actualité, dictionnaire, carte routière, pense-bête, etc.). Les widgets interactifs proposent habituellement des informations ou des divertissements. Par exemple, certains affichent les cours de la bourse ou des informations météorologiques alors que d'autres permettent de jouer à des jeux vidéo généralement assez basiques org.junit Class Assert java.lang.Object org.junit.Assert public class Assert extends java.lang.Object Un ensemble de méthodes d'assertion utiles pour l'écriture de tests. Ces méthodes peuvent être utilisées directement: Assert.assertEquals (...), cependant, elles sont plus efficaceslorsqu’elles sont référencées par import static import static org.junit.Assert.*; ... assertEquals(...); - 14 - La classe SingletonWidgetJeuxAvancesTest doit introduire une méthode de test contenant trois assertions : - La première assertion vérifie que getInstance renvoie bien un objet. - La deuxième assertion vérifie que l’objet renvoyé par getInstance est une instance de Singleton. - La dernière assertion vérifie que deux appels successifs de getInstance renvoient le même objet static void assertEquals(long expected, long actual) Asserts that two longs are equal. static void assertNotNull(java.lang.Object object) Asserts that an object isn't null. static void assertNotNull(java.lang.String message, java.lang.Object object) Asserts that an object isn't null. static void assertTrue(boolean condition) Asserts that a condition is true. static void assertTrue(java.lang.String message, boolean condition) Asserts that a condition is true. - 15 -