Voici ce que MSDN a à dire sous Quand utiliser les classes statiques :
static class CompanyInfo { public static ssortingng GetCompanyName() { return "CompanyName"; } public static ssortingng GetCompanyAddress() { return "CompanyAddress"; } //... }
Utilisez une classe statique comme unité d’organisation pour les méthodes non associées à des objects particuliers. De plus, une classe statique peut rendre votre implémentation plus simple et plus rapide car vous n’avez pas besoin de créer un object pour appeler ses méthodes. Il est utile d’organiser les méthodes dans la classe de manière significative, comme les méthodes de la classe Math dans l’espace de noms System.
Pour moi, cet exemple ne semble pas couvrir de très nombreux scénarios d’utilisation possibles pour les classes statiques. Dans le passé, j’ai utilisé des classes statiques pour les suites sans état de fonctions connexes, mais c’est à peu près tout. Alors, dans quelles circonstances une classe devrait-elle (et ne devrait-elle pas) être déclarée statique?
J’ai écrit mes pensées sur les classes statiques dans une réponse antérieure de Stack Overflow: Classer avec une méthode unique – meilleure approche?
J’aimais les classes utilitaires remplies de méthodes statiques. Ils ont fait une grande consolidation des méthodes d’assistance qui risquaient autrement d’entraîner une redondance et un problème de maintenance. Ils sont très faciles à utiliser, pas d’instanciation, pas d’élimination, il suffit de fire’n’forget. Je suppose que c’était ma première tentative involontaire de créer une architecture orientée services – beaucoup de services sans état qui faisaient juste leur travail et rien d’autre. À mesure qu’un système grandit, des dragons arrivent.
Polymorphisme
Disons que nous avons la méthode UtilityClass.SomeMethod qui bourdonne joyeusement. Tout à coup, nous devons modifier légèrement la fonctionnalité. La plupart des fonctionnalités sont les mêmes, mais nous devons néanmoins modifier quelques parties. Sans la méthode statique, nous pourrions créer une classe dérivée et modifier le contenu de la méthode selon les besoins. Comme c’est une méthode statique, nous ne pouvons pas. Bien sûr, si nous avons juste besoin d’append des fonctionnalités avant ou après l’ancienne méthode, nous pouvons créer une nouvelle classe et appeler l’ancienne à l’intérieur de celle-ci – mais ce n’est que du brut.
Les malheurs de l’interface
Les méthodes statiques ne peuvent pas être définies via des interfaces pour des raisons logiques. Et comme nous ne pouvons pas remplacer les méthodes statiques, les classes statiques sont inutiles lorsque nous devons les faire circuler par leur interface. Cela nous empêche d’utiliser des classes statiques dans le cadre d’un modèle de stratégie. Nous pourrions corriger certains problèmes en faisant passer des delegates au lieu d’interfaces .
Essai
Cela va fondamentalement de pair avec les problèmes d’interface mentionnés ci-dessus. Comme notre capacité à interchanger les implémentations est très limitée, nous aurons également du mal à remplacer le code de production par un code de test. Encore une fois, nous pouvons les envelopper, mais cela nous obligera à changer de grandes parties de notre code pour pouvoir accepter les wrappers au lieu des objects réels.
Favorise les blobs
Comme les méthodes statiques sont généralement utilisées comme méthodes utilitaires et que les méthodes utilitaires ont généralement des objectives différents, nous nous retrouverons rapidement avec une grande classe remplie de fonctionnalités non cohérentes – idéalement, chaque classe devrait avoir un objective unique au sein du système. Je préférerais avoir cinq fois plus de cours tant que leurs objectives sont bien définis.
Paramètre de fluage
Pour commencer, cette petite méthode statique mignonne et innocente pourrait prendre un seul paramètre. À mesure que la fonctionnalité augmente, deux nouveaux parameters sont ajoutés. Bientôt, des parameters supplémentaires sont facultatifs, nous créons donc des surcharges de la méthode (ou ajoutons simplement des valeurs par défaut, dans les langues qui les supportent). Avant longtemps, nous avons une méthode qui prend 10 parameters. Seuls les trois premiers sont vraiment nécessaires, les parameters 4-7 sont facultatifs. Mais si le paramètre 6 est spécifié, 7-9 doivent également être renseignés … Si nous avions créé une classe dans le seul but de faire ce que cette méthode statique faisait, nous pourrions résoudre ce problème en prenant les parameters requirejs dans le constructeur, et permettant à l’utilisateur de définir des valeurs facultatives via des propriétés ou des méthodes permettant de définir plusieurs valeurs interdépendantes en même temps. De plus, si une méthode a atteint une telle complexité, elle doit de toute façon être dans sa propre classe.
Demandant aux consommateurs de créer une instance de classes sans raison
L’un des arguments les plus courants est le suivant: pourquoi exiger que les consommateurs de notre classe créent une instance pour invoquer cette méthode unique, sans avoir à utiliser l’instance par la suite? La création d’une instance de classe est une opération très peu coûteuse dans la plupart des langues. La vitesse n’est donc pas un problème. Ajouter une ligne de code supplémentaire au consommateur est un faible coût pour jeter les bases d’une solution beaucoup plus maintenable à l’avenir. Et enfin, si vous voulez éviter de créer des instances, créez simplement un wrapper singleton de votre classe qui permet une réutilisation facile – bien que cela oblige votre classe à être sans état. Si ce n’est pas sans état, vous pouvez toujours créer des méthodes d’encapsulation statiques qui gèrent tout, tout en vous offrant tous les avantages à long terme. Enfin, vous pouvez également créer une classe qui cache l’instanciation comme s’il s’agissait d’un singleton: MyWrapper.Instance est une propriété qui renvoie simplement le new MyClass();
Seulement un Sith traite en absolus
Bien sûr, il y a des exceptions à mon aversion pour les méthodes statiques. Les vraies classes d’utilitaires qui ne présentent aucun risque de gonflement sont d’excellents exemples pour les méthodes statiques – System.Convert, par exemple. Si votre projet est unique et ne nécessite aucune maintenance ultérieure, l’architecture globale n’est pas vraiment importante – statique ou non, cela n’a pas vraiment d’importance -, cependant, la vitesse de développement est très importante.
Normes, normes, normes!
L’utilisation de méthodes d’instance ne vous empêche pas d’utiliser également des méthodes statiques, et inversement. Tant qu’il y a un raisonnement derrière la différenciation et qu’il est standardisé. Il n’y a rien de pire que de regarder une couche métier aux méthodes d’implémentation différentes.
Lorsque vous décidez de rendre une classe statique ou non statique, vous devez examiner les informations que vous essayez de représenter. Cela implique un style de programmation plus « ascendant » où vous vous concentrez sur les données que vous représentez en premier. La classe dans laquelle vous écrivez est-elle un object du monde réel, comme un rocher ou une chaise? Ces choses sont physiques et ont des atsortingbuts physiques tels que la couleur, le poids qui vous indique que vous pouvez vouloir instancier plusieurs objects avec des propriétés différentes. Je pourrais vouloir une chaise noire ET une chaise rouge en même temps. Si vous avez besoin de deux configurations en même temps, vous saurez instantanément que vous voudrez l’instancier en tant qu’object, afin que chaque object puisse être unique et existe en même temps.
Par ailleurs, les fonctions statiques ont tendance à prêter davantage aux actions qui n’appartiennent pas à un object du monde réel ou à un object que vous pouvez facilement représenter. Rappelez-vous que les prédécesseurs de C # sont C ++ et C où vous pouvez simplement définir des fonctions globales qui n’existent pas dans une classe. Cela donne plus à la programmation « descendante ». Les méthodes statiques peuvent être utilisées dans ces cas où il n’est pas logique qu’un object exécute la tâche. En vous obligeant à utiliser des classes, vous simplifiez le regroupement des fonctionnalités associées, ce qui vous permet de créer plus de code maintenable.
La plupart des classes peuvent être représentées par des éléments statiques ou non statiques, mais en cas de doute, retournez simplement à vos racines OOP et essayez de réfléchir à ce que vous représentez. Est-ce un object qui effectue une action (une voiture qui peut accélérer, ralentir, tourner) ou quelque chose de plus abstrait (comme afficher une sortie).
Entrez en contact avec votre POO intérieure et vous ne pouvez jamais vous tromper!
Pour C # 3.0, les méthodes d’extension ne peuvent exister que dans les classes statiques de niveau supérieur.
Si vous utilisez des outils d’parsing de code (par exemple, FxCop ), il vous est recommandé de marquer une méthode static
si cette méthode n’accède pas aux données d’instance. Le raisonnement est qu’il y a un gain de performance. MSDN: CA1822 – Marquer les membres comme étant statiques .
C’est plus une directive qu’une règle, vraiment …
J’ai tendance à utiliser des classes statiques pour les usines. Par exemple, ceci est la classe de journalisation dans l’un de mes projets:
public static class Log { private static readonly ILoggerFactory _loggerFactory = IoC.Resolve(); public static ILogger For(T instance) { return For(typeof(T)); } public static ILogger For(Type type) { return _loggerFactory.GetLoggerFor(type); } }
Vous avez peut-être même remarqué que l’IoC est appelé avec un accesseur statique. La plupart du temps pour moi, si vous pouvez appeler des méthodes statiques sur une classe, c’est tout ce que vous pouvez faire. Je marque la classe comme statique pour plus de clarté.
J’ai commencé à utiliser des classes statiques lorsque je souhaitais utiliser des fonctions plutôt que des classes comme unité de réutilisation. Auparavant, j’étais tout au sujet de la perversité des classes statiques. Cependant, l’apprentissage du F # m’a fait voir sous un nouveau jour.
Qu’est-ce que je veux dire par là? Eh bien, disons en travaillant sur du code super DRY , je me retrouve avec un tas de classes à une méthode. Je peux simplement insérer ces méthodes dans une classe statique, puis les injecter dans des dépendances à l’aide d’un délégué. Cela joue également bien avec mon conteneur d’ dependency injection (DI) de choix Autofac.
Bien sûr, prendre une dépendance directe à une méthode statique est toujours mal (il y a des utilisations non-diaboliques).
J’utilise des classes statiques pour définir une “fonctionnalité supplémentaire” qu’un object d’un type donné pourrait utiliser dans un contexte spécifique. Habituellement, ils se révèlent être des classes d’utilité.
En dehors de cela, je pense que “Utiliser une classe statique comme unité d’organisation pour les méthodes non associées à des objects particuliers”. décrire assez bien leur utilisation prévue.
Les classes statiques sont très utiles et ont une place, par exemple les bibliothèques.
Le meilleur exemple que je puisse fournir est la classe Math .Net, une classe statique d’espace de noms système qui contient une bibliothèque de fonctions mathématiques.
C’est comme n’importe quoi d’autre, utilisez le bon outil pour le travail, et sinon tout peut être abusé.
Rejeter à blanc les classes statiques comme étant incorrectes, ne les utilisez pas, ou dire “il ne peut y en avoir qu’une” ou aucune, est aussi faux que de les utiliser.
C # .Net contient un certain nombre de classes statiques utilisées comme la classe Math.
Donc, étant donné la mise en œuvre correcte, ils sont extrêmement utiles.
Nous avons une classe TimeZone statique qui contient un certain nombre de fonctions de fuseau horaire liées aux affaires, il n’est pas nécessaire de créer plusieurs instances de la classe, comme la classe Math contient un ensemble de fonctions (méthodes) temporelles accessibles globalement dans une classe statique .
C’est une autre question ancienne mais très critique depuis que la POO est entrée en jeu. Il ya de nombreuses raisons d’utiliser (ou non) une classe statique, bien sûr, et la plupart d’entre elles ont été couvertes par la multitude de réponses.
Je vais simplement append mes 2 cents à cela, en disant que je fais une classe statique, quand cette classe est quelque chose qui serait unique dans le système et qui n’aurait vraiment aucun sens d’en avoir dans le programme. Cependant, je réserve cette utilisation pour les grandes classes. Je ne déclare jamais de telles petites classes comme dans l’exemple MSDN comme “statiques” et certainement pas les classes qui vont être membres d’autres classes.
J’aime aussi noter que les méthodes statiques et les classes statiques sont deux choses à considérer. Les principaux inconvénients mentionnés dans la réponse acceptée concernent les méthodes statiques. Les classes statiques offrent la même flexibilité que les classes normales (en ce qui concerne les propriétés et les parameters) et toutes les méthodes utilisées doivent être pertinentes par rapport à l’objective de la classe.
Un bon exemple, à mon avis, d’un candidat pour une classe statique est une classe “FileProcessing”, qui contiendrait toutes les méthodes et propriétés pertinentes pour les différents objects du programme pour effectuer des opérations FileProcessing complexes. Cela n’a guère de sens d’avoir plus d’une instance de cette classe et être statique le rendra facilement accessible à tout dans votre programme.
Je n’utilise que des classes statiques pour les méthodes d’aide, mais avec l’arrivée de C # 3.0, je préfère utiliser des méthodes d’extension pour celles-ci.
J’utilise rarement des méthodes de classes statiques pour les mêmes raisons pour lesquelles j’utilise rarement le “modèle de conception” singleton.
Basé sur MSDN :
Exemple: les calculs mathématiques (valeurs mathématiques) ne changent pas [CALCUL STANDARD POUR LES VALEURS DÉFINIES]