2010-07-27 13 views
54

En general, vivo según la regla de que las variables/funciones globales son malas y que cada fragmento de código debe vivir en la clase a la que pertenece.Si una clase de "Utilidades" es mala, ¿dónde pongo mi código genérico?

Esta es una regla muy fácil de seguir, y creo que nunca he tenido un problema con esta regla hasta ahora.

Hoy, sin embargo, necesito agregar una función a mi ensamblaje en lugar de a una clase específica. Es decir, casi todas mis clases podrían tener un uso para esta función en particular.

¿Dónde debo poner esta función (sobrecarga de +1)?

Si lo puse en una clase de "Utilidades", me siento sucio. Si lo conecto a una clase semi relacionada, y dejo que otras clases lo llamen directamente, me siento peor.

Esta pieza de código en particular básicamente corta un IList<PointF> en una lista normalizada. Siento ahora que agregarlo como un método de extensión en IList<PointF> puede ser la mejor opción ...

+1

Estoy de acuerdo, las variables globales son malvadas. Parecen tener sus propias mentes dedicadas a socavar su código. –

+19

El estado global es problemático, pero las funciones globales son solo lógicas que se pueden volver a usar con muy pocos elementos de entrada que valga la pena encapsular en una clase. No veo ningún problema en absoluto con los métodos de Ayuda o Utilidad agrupados en las clases estáticas de Ayuda o Utilidad apropiadamente nombradas. –

+0

Prefiero usar el "Método Pull Up" en lugar de la clase Utility/Helper - [Pull Up Method] (https: // refactoring.guru/pull-up-method) –

Respuesta

26

Si se trata de una operación en un IList<PointF>, entonces debe ser un método de extensión en IList<PointF>.

En general, se deben evitar las clases de tipo Utils y Helper. Muy a menudo, encontrará que lo que piensa es un método de utilidad, es en realidad un método bastante específico que probablemente pertenece a una clase propia (como usted dice). Sin embargo, habrá casos específicos de dominio donde las clases de tipo Util (clases que agrupan métodos útiles relacionados) sean entidades válidas.

+3

+1 Los métodos de extensión son perfectos para este tipo de problema – Diadistis

+1

Sí, pero mi reserva aquí es que si se trata de una extensión, entonces debe tener un nombre que suene con fluidez ... algo así como ' points.NormalizeIntoSegments (50) ', en lugar de mis' Utilities.Segment (points, 50) 'preferidos. –

+0

¿qué pasa con la clase NormalizedIList extends IList? – atk

4

Debería ponerlo en una clase 'ListUtilities' o PointListUtilities, por supuesto. Entonces no está rompiendo el principio de responsabilidad única, que es el problema principal con una clase general de 'Utilidades'.

9

No hay nada de malo con las variables y métodos "globales". Los usas todo el tiempo Al framework le gusta llamarlos clases "estáticas" o métodos "estáticos".

Rara vez es necesario, pero generalmente agrego una clase estática interna Util en el espacio de nombres que el método/variable es necesario para C# y un módulo para VB.NET.

muestras de .NET Framework

  • System.Collections.Specialized.CollectionsUtil
  • System.Net.WebUtility
  • consultar el código fuente de Microsoft para .NET Framework. Encontrará numerosas clases de utilidad interna.
+1

Observe que todos los ejemplos del BCL se agrupan en torno a una responsabilidad particular. No hay clases genéricas de 'Utils' en ninguna parte. –

+0

¿Qué es BCL? ¿Te refieres a Bibliotecas de clase base (BCL)? – AMissico

+1

Open * .NET Reflector *. Busque "util". Hay 256 ejemplos que usan los ensamblados 4.0 predeterminados (BCL) cargados por * .NET Reflector *. – AMissico

Cuestiones relacionadas