J'ai le code suivant:
public void moveCameraTo(Location location){
moveCameraTo(location.getLatitude(), location.getLongitude());
}
public void moveCameraTo(double latitude, double longitude){
LatLng latLng = new LatLng(latitude, longitude);
moveCameraTo(latLng);
}
public void moveCameraTo(LatLng latLng){
GoogleMap googleMap = getGoogleMap();
cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, INITIAL_MAP_ZOOM_LEVEL);
googleMap.moveCamera(cameraUpdate);
}
Je pense qu'avec cette façon j'élimine la responsabilité de savoir ce qui est LatLng
dans une autre classe, par exemple.
Et vous n'avez pas besoin de préparer les données avant d'appeler la fonction.
Qu'est-ce que tu penses?
Cette approche a-t-elle un nom? Est-ce vraiment une mauvaise pratique?
design
design-patterns
clean-code
code-smell
bad-code
Tlaloc-ES
la source
la source
LatLng
des clients de cetteCamera
classe, alors vous ne voulez probablement pas l'moveCameraTo(LatLng)
êtrepublic
.moveCameraToLocation
etmoveCameraTo
/moveCameraToCoords
. Je ne voudrais certainement pas passer Location / lat / long tous sous les mêmes noms.Réponses:
Vous utilisez votre fonctionnalité de surcharge de méthode de langues pour offrir à l'appelant d'autres moyens de résoudre la dépendance des méthodes sur les informations de position. Vous déléguez ensuite à une autre méthode pour résoudre le travail restant de mise à jour de la caméra.
L'odeur de code ici serait si vous continuez simplement à étendre la chaîne de méthodes appelant des méthodes. La méthode de prise de position appelle la méthode de prise double qui appelle la méthode de prise latLng qui appelle finalement quelque chose qui sait comment mettre à jour la caméra.
Les longues chaînes ne sont aussi solides que leur maillon le plus faible. Chaque extension de la chaîne augmente l'empreinte du code qui doit fonctionner ou cette chose se casse.
C'est une conception bien meilleure si chaque méthode emprunte le chemin le plus court possible pour résoudre le problème qui lui a été présenté. Cela ne signifie pas que chacun doit savoir comment mettre à jour la caméra. Chacun doit traduire son type de paramètre de position en un type uniforme qui peut être transmis à quelque chose qui sait comment mettre à jour la caméra lorsque ce type est présenté.
Faites-le de cette façon et vous pouvez en supprimer un sans casser la moitié de tout le reste.
Considérer:
Cela rend le problème de latitude et de longitude
LatLng
. Le coût est qu'il diffuse les connaissancesLatLng
autour. Cela peut sembler cher, mais d'après mon expérience, c'est une alternative préférable à l'obsession primitive, ce qui vous empêche de créer un objet paramètre .Si
Location
est refacturable maisLatLng
ne l'est pas, envisagez de résoudre ce problème en ajoutant une usine àLocation
:Cela évite également joliment l'obsession primitive.
la source
LatLng
ou desLocation
objets. Vous pouvez montrer la relation entre les deux avecNew LatLng(Location)
ouLocation.toLatLng()
si vous devez passer de l'un à l'autre.Il n'y a rien de particulièrement mal avec votre solution.
Mais ma préférence personnelle serait que ces méthodes ne soient pas si utiles. Et compliquez simplement l'interface de tout objet dont ils font partie.
Le
void moveCameraTo(double latitude, double longitude)
ne simplifie pas vraiment le code, car je ne vois aucun problème appelant simplementmoveCameraTo(new LatLng(latitude, longitude));
à sa place. Cette méthode sent aussi l'obsession primitive.Le
void moveCameraTo(Location location)
pourrait être mieux résolu en prouvant laLocation.ToLatLng()
méthode et en appelantmoveCameraTo(location.ToLatLng())
.si c'était C # et si de telles méthodes étaient vraiment nécessaires, je les préférerais comme méthodes d'extension au lieu de méthodes d'instance. L'utilisation de méthodes d'extension deviendrait vraiment évidente si vous essayiez l'abstrait et testiez unitaire cette instance. Comme il serait beaucoup plus facile de simuler une seule méthode au lieu de plusieurs surcharges avec des conversions simples.
Je ne vois aucune raison pour laquelle ce serait un problème. Tant que votre code référence la classe qui contient
void moveCameraTo(LatLng latLng)
, cela dépend toujours indirectementLatLng
. Même si cette classe n'est jamais directement instanciée.Je ne comprends pas ce que tu veux dire. Si cela signifie créer une nouvelle instance ou transformer des classes les unes des autres, je n'y vois aucun problème.
En y réfléchissant, je pense que ce que je dis est également pris en charge par la conception API de .NET lui-même. Historiquement, de nombreuses classes .NET ont suivi votre approche consistant à avoir de nombreuses surcharges avec différents paramètres et de simples conversions à l'intérieur. Mais c'était avant que les méthodes d'extension n'existent. Les classes .NET plus modernes sont plus légères dans leurs propres API et s'il existe des méthodes avec des surcharges de paramètres, elles sont fournies en tant que méthodes d'extension. Un exemple plus ancien est NLog ILogger qui a des dizaines de surcharges pour l'écriture dans le journal. Comparez cela aux nouveaux Microsoft.Extensions.Logging.ILogger qui ont un total de 3 méthodes (et seulement 1 si vous comptez vous connecter). Mais il existe de nombreux assistants et diverses paramétrisations comme méthodes d'extension .
Je pense que cette réponse montre que certaines langues auraient des outils pour rendre le design comme celui-ci plus agréable. Je ne connais pas beaucoup Java, donc je ne sais pas s'il y aurait un équivalent. Mais même l'utilisation de méthodes statiques simples peut être une option.
la source
moveCameraTo(new LatLng(latitude, longitude));
dans n'importe quel endroit du projet, mais je pense que c'est plus clair d'utiliser directement le moveCametaTo (latLng), c'est comme un fichier en java que vous pouvez passer comme une chaîne, ou comme une classe PathJe ne sais pas quel est le nom correct pour cela, s'il en a un, mais c'est une bonne pratique. Vous exposez plusieurs surcharges, permettant à la classe appelante de déterminer le jeu de paramètres qu'elle souhaite utiliser. Comme vous le dites, une autre classe peut ne pas savoir ce qu'est un
LatLng
objet, mais peut le savoirLocation
.Avoir une méthode appeler l'autre est également essentiel, car vous ne voulez pas de code dupliqué entre ces méthodes. Comme vous l'avez fait, choisissez une méthode pour être celle qui fait le travail et demandez aux autres méthodes de l'appeler (directement ou indirectement)
la source
Si cela vous dérange d'utiliser des méthodes, c'est juste une fonctionnalité de surcharge de méthode, c'est bien.
Mais cela n'élimine pas la responsabilité de savoir ce qu'est un LatLng . Parce que vous initialisez
LatLng latLng = new LatLng(latitude, longitude)
. C'est une dépendance totale àLatLng
. (Pour comprendre pourquoi l'initialisation est un problème de dépendance, vous pouvez vérifier l' injection de dépendance ) La création d'une méthode surchargée aide simplement les clients qui ne s'en soucient pasLatLng
. Si vous voulez dire cela, c'est aussi bien mais je ne pense pas que ce soit une approche. Il s'agit simplement de nombreuses méthodes de service pour les clients.Il existe donc deux options pour concevoir votre architecture:
Je m'enfuis le plus possible en créant des méthodes qui nécessitent des types primitifs comme paramètres (Option 1). Parce que si votre entreprise change plusieurs fois et que vous devez lire les paramètres de méthode, il est très difficile de modifier et d'implémenter toutes les fonctions d'appel.
Au lieu de cela, utilisez des interfaces (injection de dépendance). Si vous pensez que c'est coûteux et prend plus de temps, utilisez des classes et fournissez leurs méthodes d'extension de mappeur (Option 2).
la source