Lorsque je crée une application, je crée généralement une classe statique qui contient des méthodes statiques et des propriétés que je n'arrive pas à trouver ailleurs.
Ce n'est pas un design particulièrement bon, mais c'est un peu le point: cela me donne un endroit pour localiser toute une classe de décisions de conception que je n'ai pas encore pensé. Généralement, lorsque l'application se développe et est affinée par le refactoring, il devient plus clair où ces méthodes et propriétés devraient effectivement résider. Heureusement, l'état des outils de refactoring est tel que ces changements ne sont généralement pas exceptionnellement douloureux à faire.
J'ai essayé de le faire dans l'autre sens, mais l'inverse consiste essentiellement à implémenter un modèle d'objet avant d'en savoir assez sur mon application pour concevoir correctement le modèle d'objet. Si je fais que, je passe beaucoup de temps et d'énergie à trouver une solution médiocre que je dois revoir et reconstruire à partir de la base à un moment donné dans le futur. Bon, d'accord, si je sais que je vais refactoriser ce code, pourquoi ne pas passer à l'étape de la conception et de la construction des classes inutilement compliquées qui ne fonctionnent pas vraiment? Par exemple, j'ai construit une application qui est utilisée par plusieurs clients. J'ai compris assez tôt que je devais avoir un moyen de séparer les méthodes qui doivent fonctionner différemment pour différents clients. J'ai construit une méthode utilitaire statique que je pouvais appeler à n'importe quel point du programme où j'avais besoin d'appeler une méthode personnalisée, et je l'ai coincée dans ma classe statique.
Cela a bien fonctionné pendant des mois. Mais il arriva un moment où il commençait tout juste à avoir l'air laid. Et j'ai donc décidé de le refactoriser dans sa propre classe.Et quand j'ai parcouru mon code en regardant tous les endroits où cette méthode était appelée, il est devenu extrêmement clair que toutes les méthodes personnalisées devaient vraiment être membres d'une classe abstraite, les assemblages des clients devaient contenir une seule classe dérivée Cela implémente toutes les méthodes abstraites, puis le programme suffit pour extraire le nom de l'assembly et de l'espace de noms de sa configuration et créer une instance de la classe d'entités personnalisées au démarrage. C'était très simple pour moi de trouver toutes les méthodes qui devaient être personnalisées, car tout ce que j'avais à faire était de trouver tous les endroits où ma méthode load-a-custom-feature était appelée. Il m'a fallu une bonne partie de l'après-midi pour parcourir toute la base de code et rationaliser cette conception, et le résultat final est vraiment flexible et robuste et résout le problème. Le fait est que, lorsque j'ai implémenté cette méthode pour la première fois (en réalité, c'était trois ou quatre méthodes interdépendantes), j'ai reconnu que ce n'était pas la bonne réponse. Mais je n'en savais pas assez pour décider quelle était la bonne réponse. Donc je suis allé avec la réponse fausse la plus simple jusqu'à ce que la bonne réponse soit devenue claire.
La question concerne C#, pas Java. Quoi qu'il en soit, la classe String est scellée (finale en Java), dans .NET et Java –