Disons que j'ai une classe Event
comme suit:
class Event {
private var attendees: [Person] = []
// Case 1
//*******
// Should I use a func…
func countOfAttendees() -> Int {
return attendees.count
}
// …or a var
var countOfAttendees: Int {
return attendees.count
}
// Case 2
//*******
// Should I use a func…
func countOfPaidAttendees() -> Int {
return attendees.filter({$0.hasPaid}).count
}
// …or a var
var countOfPaidAttendees: Int {
return attendees.filter({$0.hasPaid}).count
}
}
Est-il recommandé d'utiliser fonctions ou propriétés calculées dans les 2 cas indiqués ci-dessus?
Suivez le niform Access Principle ,
Tous les services offerts par un module doivent être disponibles via une notation uniforme, qui ne trahit pas s'ils sont implémentés par le stockage ou par le calcul
Pour moi, cela signifie que je n'écris pas de fonctions qui ne prennent aucun argument et renvoient une valeur. J'utilise toujours des propriétés calculées. De cette façon, si je décide par la suite de changer la propriété calculée en une propriété stockée, je peux le faire sans avoir envie de supprimer les parens partout dans mon application et sans avoir une méthode "getter" distincte qui renvoie simplement la valeur d'une propriété stockée propriété, ce qui semble IMHO assez gaspillage.
Et si je change une propriété stockée en une propriété calculée, je n'ai pas besoin d'ajouter de parens à la fin de celle-ci, et partout où elle est utilisée dans l'application.
Je dirais que cela dépend de la complexité du calcul par rapport à la fréquence d'utilisation.
O(1)
/*
, Alors utilisez la propriété calculée.O(N)+
/rare-use
, Alors utilisez la fonction.O(N)+
/frequent-use
, Pensez si à l'avenir vous pourriez décider d'utiliser la mise en cache ou d'autres techniques "intelligentes" pour compenser la complexité, si "oui" alors utilisez la propriété, si " non-non-non, c'est juste lourd "puis utilisez la fonction.J'ai récemment commencé à apprendre Kotlin et ils ont une excellente heuristique sur le moment d'utiliser les propriétés calculées:
Fonctions vs propriétés
Dans certains cas, les fonctions sans argument peuvent être interchangeables avec des propriétés en lecture seule. Bien que la sémantique soit similaire, il existe certaines conventions stylistiques sur le moment de préférer l'une à l'autre.
Préférez une propriété à une fonction lorsque l'algorithme sous-jacent:
- ne jette pas
- a une complexité O(1)
- est bon marché à calculer (ou a pu être effectué lors de la première exécution)
- renvoie le même résultat lors des invocations
- https://kotlinlang.org/docs/reference/coding-conventions.html
Dans Swift, les fonctions sans paramètres et propriétés calculées ont presque les mêmes capacités (il peut y avoir une différence qu'une fonction sans paramètre est également une fermeture, alors qu'une propriété calculée ne l'est pas).
La différence est sémantique. Si votre code effectue une action et retourne par exemple une description du résultat de cette action, alors j'utiliserais une fonction. Si votre code calcule une propriété mais du point de vue de l'utilisateur, cela aurait pu être une propriété stockée, ou peut-être une propriété stockée qui nécessite d'abord la mise à jour d'une valeur mise en cache, alors j'utiliserais une propriété calculée.
Une grande différence: que se passe-t-il si vous appelez deux fois la fonction ou la propriété calculée? Pour une propriété calculée, je m'attends à ce que x = propriété; la propriété y = a exactement le même comportement que la propriété x =; y = x sauf qu'il peut fonctionner un peu plus lentement. Pour les fonctions, je ne serais pas surpris si le comportement était différent.
Utilisez countOfAttendees
et countOfPaidAttendees()
.
Une variable calculée est une variable qui renvoie une valeur calculée à chaque fois qu'elle est accédée. Autrement dit, il ne stocke pas de valeur. En interne, il est implémenté en fonction.
Quelle est la différence avec une fonction?
Vous devez utiliser une variable lorsque
Raisons non pertinentes de préférer une variable à une fonction
De WWDC 2014 - 204 Quoi de neuf dans Cocoa > 24:40 Quand utiliser un @property
Utilisez la propriété pour tout ce qui concerne la valeur ou l'état d'un objet ou sa relation avec d'autres objets. Mauvais candidats:
- Méthodes qui font les choses: charger, analyser, basculer,…. Ils ont des verbes en son nom.
- Générateurs: init, copy, énuméré,…. Ces méthodes ne sont pas idempotentes.
- Méthodes qui changent d'état: nextObject.
De Swift Style par Erica Sadun > Propriétés calculées vs méthodes
Une propriété exprime la qualité inhérente d'une instance, tandis qu'une méthode effectue une action.
- Les méthodes ont des paramètres; les propriétés ne le font pas. Préférez les méthodes pour tout appel avec effets secondaires. Si une méthode fait quelque chose (par exemple, elle charge, analyse, bascule ou imprime) ou a un nom de verbe, elle ne doit pas être une propriété.
- Préférez les propriétés des valeurs simples que vous pouvez obtenir et/ou définir.
- Les propriétés doivent exprimer une qualité intrinsèque sémantique d'une instance de type.
- Les propriétés vous permettent d'ajouter des observateurs via willSet et didSet. Contrairement aux propriétés d'instance stockées, les propriétés de type stockées doivent toujours recevoir une valeur par défaut.
De Conventions de codage Kotlin> fonctions vs propriétés . Voir réponse de Daniel ci-dessus .
Autres ressources sans informations pertinentes:
J'utiliserais un func
. La programmation orientée objet fonctionne très bien sans propriétés calculées. Parce que vous récupérez une valeur qui a été calculée/filtrée, certains peuvent affirmer qu'une propriété calculée se sent bien. Mais voici ma plainte, si vous faites cela, alors la lisibilité prend un coup, car cela ressemble à une valeur.
Dans ce contexte, cela n'aurait aucun sens d'essayer d'attribuer la valeur calculée (et heureusement, le IDE nous aide à éviter cela), mais que se passe-t-il si j'essaie d'affecter quelque chose qui est calculé mais qui ressemble à un valeur?
event.countOfAttendees = 0; // not possible
Lorsque vous utilisez func, l'appelant sait que vous ne traitez pas directement avec une valeur:
event.countOfAttendees()
Je pense que si c'est un objet comportemental, il devrait ressembler à un comportement plutôt qu'à une structure de données. Si votre objet est stupide et n'a aucun comportement, alors pourquoi essayer de l'encapsuler? Dans ce cas, vous pourriez tout aussi bien que les participants soient publics