J'ai une fonction statique qui est limitée à un certain contexte, par exemple uniquement pour les documents. Il existe 2 façons de le définir comme fonction ou fonction de premier niveau dans un objet.
1.
package com.armsoft.mtrade.data.pref import com.armsoft.mtrade.App import com.armsoft.mtrade.domain.model.DocSaveType fun setOrderSaveType(orderSaveType: DocSaveType) { val context = App.getContext() val sharedPreferences = context.getSharedPreferences(DocPrefManager.DOC_PREF, 0) val editor = sharedPreferences.edit() editor.putString(DocPrefManager.KEY_ORDER_SAVE_TYPE, orderSaveType.getCode()) editor.commit() }
2.
package com.armsoft.mtrade.data.pref import com.armsoft.mtrade.App import com.armsoft.mtrade.domain.model.DocSaveType object DocPrefManager { private const val DOC_PREF = "DOC_PREF" private const val KEY_ORDER_SAVE_TYPE = "KEY_ORDER_SAVE_TYPE" @JvmStatic fun setOrderSaveType(orderSaveType: DocSaveType) { val context = App.getContext() val sharedPreferences = context.getSharedPreferences(DOC_PREF, 0) val editor = sharedPreferences.edit() editor.putString(KEY_ORDER_SAVE_TYPE, orderSaveType.getCode()) editor.commit() } }
5 Réponses :
objet Clazz
sera compilé en tant que singleton, la fonction de niveau supérieur sera compilée en tant que statique dans JVM.
s'il n'y a aucune raison pour que votre méthode soit en instance, la méthode statique (objet compagnon de premier niveau) serait un peu plus performante. (ref: https://stackoverflow.com/a/11993118/5354658 )
Bien que l'approche recommandée consiste à utiliser des déclarations de niveau supérieur lorsque cela est possible, les fonctions qui ne sont utilisées que dans des contextes spécifiques doivent être étendues à ce contexte et déclarées dans le champ pertinent classe. Les fonctions de niveau supérieur sont particulièrement utiles pour définir les fonctions d'assistance ou utilitaire . Un exemple serait les fonctions des collections dans la bibliothèque standard Java, qui ont une portée vraiment globale. La même chose s'applique aux constantes. Lisez la discussion sous cette réponse https://stackoverflow.com/a/48820895/1635488
Dans votre cas, DocPrefManager
a un contexte spécifique. De plus, je suppose que vous ne voulez pas polluer la liste d'auto-complétion IDE avec des fonctions spécifiques. Cela conduit à une non-maintenabilité.
P.S. Les fonctions de DocPrefManager
ne devraient pas dépendre de App.getContext (). La classe DocPrefManager
doit être initialisée avec un contexte et dans ce cas, l'utilisation des fonctions de niveau supérieur est étrange, car vos fonctions ne seraient pas statiques.
KotlinConf 2017 - Vous pouvez, mais devriez-vous? par Mike Gouline recommande que nous devrions utiliser la fonction de premier niveau avec précaution car elle peut provoquer une "pollution par saisie semi-automatique".
Mais, BTW, Andrey Breslav considérait la fonction de haut niveau comme sa fonctionnalité de langage la plus préférée dans KotlinConf 2018 - Panneau de fermeture.
Astuce pour les projets multi-modules:
Utilisez le modificateur de visibilité
internal
pour étendre une fonction de niveau supérieur à son module contenant afin qu'elle ne pollue pas l'auto-complétion de l'EDI dans des modules non liés.// module A internal fun doSomething() { // ... } // module B doSomething() // (!) Cannot access 'doSomething': it is internal in module A // Does NOT show up in module B's auto-complete