Approche Orienté Objet

Fermé
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017 - 21 juil. 2017 à 01:03
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 - 22 juil. 2017 à 21:07
Bonjour, Voilà je développe actuellement une mini api qui consiste a calculer le prix d'un appel téléphonique . Pour ce faire je dois faire appels à certaines classes extérieurs de la libraire Time qui me permettront de connaitre la durée de l'appel ainsi que la date et l'heure de celui-çi voici les classes requises : LocalDateTime et Duration . Cependant n'ayant pas l'habitude de manipuler des classes "extérieur" présentant des multitudes de méthodes je m'y perds un peu .... voici ma class :
import java.time.LocalDateTime;
import java.time.Duration;

public class PhoneCall {
 
private LocalDateTime callDate;
private Duration callTiming ;

public PhoneCall (LocalDateTime callDate, Duration callTiming) {
   this.callDate = callDate; // Pas certains qu'il faille l'initialisé de cette manière ...
   this.callTiming = callTiming // Pas certains qu'il faille l'initialisé de cette manière ... 
}


public LocalDateTime getCallDate() {
   return callDate;
}

public Duration getCallTiming() {
   return callTiming;
}
	
}


Comme vous-avez pu le remarqué j'ai un doute en ce qui concerne l'initialisation de mes 2 attributs , sachant qu'ils ont pour type 2 class de la librairie Time je ne sais pas si C'est la bonne façon de les initialisés je m'explique ayant utilisé la class LocalDate auparavant pour initialisé mon attribut on m'a dis de procédé de cette façon : date = LocalDate.now(); du coup sachant que cette class aussi appartient a la librairie Time je me demandais si je devais procédé de la même façon et si c'est le cas Qu'elle est la différence entre ces 2 initialisations : this.date = date et date = LocalDate.now();. Je voudrais également savoir Quel Exception devrais-je prévoir Merci d'avance ! .

1 réponse

KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
21 juil. 2017 à 12:11
Bonjour,

Je ne pense pas que le problème soit lié à l'utilisation des classes time, car tu pourrais (devrais) te poser les même questions pour n'importe quelle classe, même si c'était des String ou d'autres objets "plus simples" en paramètre du constructeur.

Tout dépend en fait ce que tu veux faire et quelles valeurs sont censés représenter tes attributs.

Si tu fais
this.callDate = callDate; this.callTiming = callTiming;
c'est lors de l'appel du
new PhoneCall(callDate, callTiming)
qu'il faudra passer les bonnes valeurs à l'objet, ce qui donne la liberté au code appelant (celui qui fait le new) de mettre ce qu'il veut comme valeurs, quitte à être complètement incohérent (date farfelue, durée négative, valeurs null, etc.)

À l'opposé ce que l'on peut faire c'est mettre aucun paramètre au constructeur et donner des valeurs par défaut... si ça a un sens !
Par exemple, quand on fait une
new ArrayList();
c'est implicitement une liste vide qui ne contient aucun élément, le tableau de données qui représente la liste est donc initialisé avec un tableau vide.

Dans ton cas, il faut donc se demander, est-ce que tous les paramètres du constructeur ont du sens, ou est-ce que l'on ne peut pas en supprimer certains au profit de valeurs par défaut ?

On peut aussi faire des calculs dans un constructeur, on donne quand même des paramètres dans le constructeur et on fait des calculs pour déterminer les valeurs des attributs. Par exemple : tu donnes la date de début et de fin de l'appel, tu calcules la durée en faisant fin-début...

Remarque : LocalDateTime et Duration ne sont pas des classes extérieures, elles sont inclues dans l'API standard Java au même titre que String, ArrayList et 4000 autres classes et interfaces. On considère qu'une classe est "extérieure" à partir du moment où tu dois télécharger un jar complémentaire et l'attacher à ton programme, ce n'est pas le cas de java.time.

De plus, ce ne sont pas des classes si complexes que ça, elles ont plein de méthodes (comme String peut en avoir aussi par exemple) mais elles représentent des choses assez simples, assimilables à un entier (comme pour la classe Date) et les méthodes permettent de faire des calculs (addition, soustraction) sur ces entiers.

Par exemple pour faire le calcul fin-début dont je parlais tout à l'heure pour calculer une durée, tu as la méthode minus :
LocalDateTime debut = ..., fin = ...;
Duration duree = fin.minus(debut);

Du coup pour ton problème, tout dépend ce que tu veux faire avec ta classe, sachant que tu peux aussi avoir plusieurs constructeurs qui offrent plusieurs manières d'initialiser ton objet.
-1
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017
22 juil. 2017 à 01:16
Super intéressant vraiment , sa montre encore une fois combien il y'a une flexibilité non négligeable en ce qui concerne la liberté au programmeur quant à l'app qu'on désire crée et ce qu'on désire en faire ! Un grand Merci pour cet éclaircissement en tout cas . Selon moi pour un début je voulais partir sur une app assez simple , c'est à dire que que la personne entre lui même les valeurs pour la date et l’heur de l'appel , ainsi que pour la durée de l'appel autrement dis C'est comme si moi en tant qu'individu j'ai passé un coup de fil et que je désir savoir le montant à payé (j'ajouterais un attribut pour le tarif afin de pouvoir calculer le cout) j'ai jeté un coup d’œil dans l'Oracle pour les classes LocalDateTime et Duration je suis tombé comme attendu sur une multitude de méthodes qui répondent à mes attentes mais ce sont des méthodes or ce que je voudrais C'est entré directement les paramètres à mon instance crée par exemple :
public class TestPhoneCall{
  public static void main(String[]args){

  LocalDateTime date1 = new LocalDateTime("2017/07/22 à 14 h 34"); // je me doute que sa soit 
 faux pour le type des valeurs entrées mais j'essaie en quelque sort d'exprimé ce que je désire faire. 
  
 Duration duree = new Duration("2 heures 54 minute , 33 secondes");

 PhoneCall pc1 = new PhoneCall(date1 , duree); 

 System.out.println(PhoneCall.toString());



Voilà en gros l'idée sur quoi je voulais allé encore une fois je concedes mon absurdité sans équivalent que je viens de faire .
0
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017
22 juil. 2017 à 05:41
En cherchant un peu j'ai su me remettre sur une piste qui m'a l'air assez cohérente de quoi voilé les absurdités que j'ai avancer auparavant , cependant je reste confronté à une erreur de débutant auquel je n'arrive par à faire face à savoir un NullPointerException(); :

public class PhoneCall {
  public static void main(String[]args){
     PhoneCall pc = null;

     pc= new PhoneCall(pc.getCallDate().of(2017, 07, 22, 23, 21) ,"00000" ,pc.getCallTiming().ofHours(2).ofMinutes(50).ofSeconds(43));
	System.out.println(pc.toString());	
	}
}



Après je penses aussi que les appels de méthodes que j'ai faites ne sont sans doute pas ce que j'aurais du privilégié mais je préféré m'en assuré
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
22 juil. 2017 à 12:24
Tu as un NullPointerException car tu fais
pc = null;
et ensuite
pc.getCallDate()
.
Les méthodes
of
sont static, donc tu ne dois pas utiliser d'objet pour les appeler mais directement le nom de la classe :
LocalDateTime.of(...)
.

Cependant ici, il y a plus simple, ce serait de mettre dans ton constructeur les différentes valeurs que tu veux saisir, puis de t'en servir pour calculer tes attributs, ainsi l'appelant n'a pas besoin de savoir comment tu construit ton objet pour l'utiliser, il est inutile qu'il construise lui même l'objet LocalDateTime ou l'objet Duration, ce qui te laisse la liberté de changer l'implémentation sans impacter le client. Par exemple, je ne suis pas convaincu que stocker la durée soit pertinent, il paraît plus simple de stocker la date de fin, et calculer la durée à la demande.

Exemple :

import java.time.Duration;
import java.time.LocalDateTime;

public class PhoneCall {

    private final LocalDateTime start;
    private final LocalDateTime end;

    public PhoneCall(int startYear, int startMonth, int startDay, int startHour, int startMinute, int startSecond, int durationHours, int durationMinutes, int durationSeconds) {
        start = LocalDateTime.of(startYear, startMonth, startDay, startHour, startMinute, startSecond);
        end = start.plusHours(durationHours).plusMinutes(durationMinutes).plusSeconds(durationSeconds);
    }

    public LocalDateTime getStart() {
        return start;
    }

    public LocalDateTime getEnd() {
        return end;
    }

    public Duration getDuration() {
        return Duration.between(start, end);
    }

    public static void main(String[] args) {
        PhoneCall call = new PhoneCall(2017, 7, 22, 12, 34, 56, 1, 2, 3);
        System.out.println(call.getStart()); // 2017-07-22T12:34:56
        System.out.println(call.getEnd()); // 2017-07-22T13:36:59
        System.out.println(call.getDuration()); // PT1H2M3S
    }
}

Remarque : dans
of(2017, 07, 22, 23, 21)
, tu as écris
07
avec un 0 devant, c'est une notation en octale, pas en décimale. Pour 07 ça ne change rien, mais si tu écrivais par exemple 010 ce serait égal à 8, 0100 est égal à 64 etc.
0
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017 > KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024
22 juil. 2017 à 18:43
Ahh d'accord je vois à présent merci pour ces pertinentes explication , je tacherais de m'en rappeler à l'avenir mais j'ai eu le temps de finir le matin mon app Pourriez-vous me dire si selon vous si la programmation que j'ai adopter présente une perte de performance quant l’implémentions ou autre ... Y'a également quelque chose qui a attiré mon attention lorsque j'ai voulu effectuer un premier appel de l'une des méthodes de la Classe Duration , les methodes proposé était "restreint" ce que je veut dire c'est que mon environnement de développement n'affichait pas toute les méthodes disponible pour la Classe Duration par contre l'or du deuxième appel d'une méthode celle si afficher une plus grand gamme de méthode disponible pour celle ci exemple :
Premier Appel , Méthode disponible pour entrer l'heure: Duration.ofHours(2);
Deuxième Appel , Méthode disponible pour entrer les minutes : Duration.ofHours(2).plusMinutes((54)) 

lors du premier appel d'une methode , la methode plusHours() n'était pas disponible pourtant c'est bien une méthode disponible de la class Duration dois - je en conclure que le premier appel de la methode doit être une méthode de class (static) ? voici mes class :


import java.time.Duration;
import java.time.LocalDateTime;

public class PhoneCall{

	private LocalDateTime callDate;
	private String number;
	private Duration callTiming;
	private static double RATE;

	public PhoneCall(LocalDateTime callDate, String number, Duration callTiming) {
		if(callDate.isAfter(callDate.now())) throw new IllegalArgumentException("La date et l heure de l'appel doit etre cohérante");
		if(callTiming.isNegative()) throw new IllegalArgumentException("La duree de l'appel ne peut pas etre négatifs");
		if(number == null || number.equals("")) throw new IllegalArgumentException("le numero ne peut pas etre une chaine vide ou null");
		if(number.length() > 9 || number.length() < 9) throw new IllegalArgumentException("le numero ne peut pas contenir plus ou moins de 9 chiffres");
		this.callDate = callDate;
		this.number= number;
		this.callTiming = callTiming;
		this.RATE = 0.15;
	}

	public PhoneCall(LocalDateTime callDate, String number, Duration callTiming, double RATE){
		this(callDate,number,callTiming);
		if (RATE <= 0) {
			throw new IllegalArgumentException();
		}
		this.RATE = RATE;
	}

	public static double getRATE() {
		return RATE;
	}

	public static void setRATE(double nRATE) {
		if (RATE <= 0) {
			throw new IllegalArgumentException();
		}
		RATE = nRATE;
	}

	public LocalDateTime getCallDate() {
		return callDate;
	}

	public String getNumber() {
		return number;
	}

	public Duration getCallTiming() {
		return callTiming;
	}
	
	public double rateCall() {
		double minutes = callTiming.toMinutes();
		return RATE * minutes;
	}

	public String toString() {
		return "Date : " + callDate+ "\nNumero Appele : " + number + "\nDuree Appel : " + callTiming
				+ "\nTarif Minute : " + RATE + " euros/minute" + "\nCout de l'appel : "  + rateCall();
	}
}



import java.time.LocalDateTime;
import java.time.Duration;
public class TestAppel {
	public static void main(String[]args){
    
    try{
    PhoneCall pc = new PhoneCall(LocalDateTime.of(2017,7, 22, 18, 00) ,"025671237" , Duration.ofHours(2).plusMinutes(54).plusSeconds(33));
	System.out.println(pc.toString());	
    }catch(IllegalArgumentException e){
     System.out.println(e.getMessage());    
    }
    
  }
}
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
22 juil. 2017 à 21:07
"mon environnement de développement n'affichait pas toute les méthodes disponible pour la Classe Duration par contre l'or du deuxième appel d'une méthode celle si afficher une plus grand gamme de méthode disponible"
Cela dépend du logiciel que tu utilises, mais parfois la vue des méthodes est limitée à celles qui sont compatibles avec le type de la variable que tu affectes.

Exemple, tu saisis
int n = duree.
l'éditeur peut ne proposer que les méthodes de l'objet
duree
dont le résultat est un
int
, celles qui renvoient un autre type seront masquées ou alors listées plus loin dans la fenêtre.

Pour ton code, il y a des incohérences, par exemple l'usage de RATE. Normalement l'usage des noms en majuscules est limité aux constantes, or ici tu modifies sa valeur. De plus il est déclaré static mais est utilisé avec un contexte non-static comme dans
this.RATE = RATE;
qui est incorrect.
Plus largement je pense que tu devrais avoir (au moins) deux classes, une qui représente la durée de l'appel, et une autre qui calcule le montant, c'est dans cette deuxième classe que devrait apparaître ta notion de "rate".
0