¿Cómo diseñas normalmente las regiones de una clase?

17

Me preguntaba si había un estándar para diseñar las regiones de una clase.

Actualmente uso

Fields
Constructor
Properties
Public Methods
Private Methods

Fieldssiendo propiedades privadas y Propertiessiendo las públicas. Normalmente usaré subregiones dentro de eso si es necesario, o ocasionalmente agregaré otras regiones a continuación (como la interfaz o los miembros de baseClass).

Rachel
fuente
1
¿Estás hablando del diseño en general o estás usando "#regions"?
snmcdonald
1
@snmcdonald Uso #regionetiquetas para definir una sección
Rachel
¿No debería ser una pregunta de la comunidad wiki? No creo que haya un estándar, y la respuesta podría cambiar dependiendo de los idiomas.
Raveline
77
Empiezo eliminando todos los #regions
Ed S.
3
@Ed S. +1 porque las regiones son el demonio. Todo lo que le permiten hacer es ocultar el hecho de que su archivo de código es demasiado grande y necesita ser refactorizado.
MattDavey

Respuestas:

4

Enumeraciones relacionadas con la clase u ocasionalmente estructuras / clases de datos puros (por encima de la definición de clase real)

--- Definición de clase ---

Miembros privados

CTOR / DTOR si el idioma tiene DTOR

Propiedades publicas

Métodos de utilidad (métodos privados o protegidos con pequeño alcance)

Funcionalidad de clase (puede dividirse en varias regiones según el alcance de la clase).

Pax Noctis
fuente
17

Sub Regiones? ¿Tu clase tiene una responsabilidad única ? (implícito en eso ... mi respuesta es "Raramente cualquier región, excepto tal vez para agrupar propiedades, constructores y métodos" ... pero aun así, no lo uso tanto)

desaparecido en combate
fuente
2
Estoy programando en WPF en este momento y un ejemplo de algunas subregiones que usaría es un ViewModel que tiene sus propiedades públicas divididas en propiedades relacionadas con la interfaz de usuario, comandos, datos, etc. Esto hace que sea mucho más fácil encontrar lo que soy buscando rápidamente
Rachel
2
¿Por qué no utilizar grandes banners de comentarios en lugar de regiones? // ----------ViewModel Properties---------- De esa manera, aún puede ver el código (o contraerlo con un esquema y ver los miembros). Las regiones son para esconder cosas. El código no debe estar oculto, a menos que sea autogenerado o algo así.
Kyralessa
1
@Rachel favorece la composición.
MattDavey
10

Solo quería confirmar que se refería a "#regiones" y no al diseño de clase en general.

Me sorprende que nadie haya mencionado para evitar el uso de regiones. Entiendo que el OP quiere realizar una encuesta sobre el diseño de las regiones, pero me gustaría plantear un punto de vista alternativo.

Evito las regiones. Me gusta ver el código con el que estoy trabajando. Si le resulta difícil encontrar lo que está buscando, utilice el plegado de código y agrupe construcciones de clase similares.

¿Por qué odio las regiones? CTRL+M,Ly CTRL+M,Oalternará el código de plegado. Sin embargo, al colapsar, oculta toda la región. Solo necesito colapsar métodos / propiedades / comentarios.

Si hay demasiadas regiones, tal vez sea un olor a código y su clase está haciendo demasiado trabajo. Jeff Atwood ofrece una buena publicación sobre regiones que vale la pena leer.

Mi cita favorita en #regions:

No, no usaré #regions. Y no, NO NEGOCIO CON TERRORISTAS. Cállate.

- Jeff Atwood

Dicho esto, sé que muchos programadores insisten en usarlos. Esta pregunta es subjetiva. Solo pensé que ofrecería una alternativa.

snmcdonald
fuente
1
Aquí hay una macro para colapsar a definiciones pero expandir regiones, en caso de que estés atascado trabajando con personas enamoradas de regiones: stackoverflow.com/questions/523220/awesome-visual-studio-macros/... Funciona bien a menos que estés trabajando con personas realmente enfermas que ponen regiones dentro de los métodos .
Kyralessa
¡Una macro muy útil! No estoy seguro de por qué no lo incorporaron al estudio visual, sin embargo, gracias.
snmcdonald
Mi jefe ama las regiones, las ama. También le encantan las clases internas privadas y los métodos enormes. Nuestro código tiene una clase con aproximadamente una docena de regiones dividiéndola, 3 clases internas y algunos métodos siempre que tengan una docena de regiones de nivel superior dentro de ellas, con subregiones dentro de ellas.
CodexArcanum
4

Varía de un idioma a otro. Como soy codificador de Delphi, tiendo a seguir la convención estándar de Delphi, que se ve así:

type
  TMyClass = class(TBaseClass)
  private
    private fields
    private methods
  protected
    protected fields
    protected methods
    protected properties
  public
    constructor(s)
    destructor
    public methods
    public properties
  end;

Me parece una buena forma de organizar la información que es fácil de leer y comprender.

Mason Wheeler
fuente
3
Me parece bastante sorprendente que privado, protegido, público y publicado estén ordenados alfabéticamente y encapsuladamente, ¡y todos comienzan con P!
Peter Turner
divertido, no lo hago. Siempre he descubierto que era más natural enumerar publicprimero, ya que a la mayoría de los usuarios solo les importan las publiccosas.
Matthieu M.
Siempre he encontrado que esta convención es una idea realmente tonta. ¿Qué tiene que ver la visibilidad con la funcionalidad? En cualquier caso, siempre he usado interfaces para definir la funcionalidad pública, pero implementé la interfaz como protegida en la clase. Los únicos elementos que agruparé consistentemente son los métodos publicados y las propiedades de los componentes, y de lo contrario siempre los agrupo por interfaces y herencia, usando palabras clave de visibilidad múltiple según sea necesario. Aquellos elementos que son exclusivos de la implementación de la clase (es decir, no reemplaza) realmente deberían enumerarse primero.
S.Robins
3

Tiendo a exponerlos de la siguiente manera:

Public fields (usually static constants)
Constructors
Public methods
Private methods
Private fields

No he usado un lenguaje que lo use, Propertiespor eso no se presentan. Puse métodos y campos privados en la parte inferior porque si alguien más está usando este archivo en su código, solo deberían preocuparse por la API, que es lo público. Y todos los editores de texto que conozco, e incluso los IDE, colocan el cursor en la parte superior al abrir archivos.

gablin
fuente
+1 para poner campos privados en la parte inferior. Agrupo los métodos públicos por la interfaz que implementan y coloco los que no implementan ninguna interfaz en la parte superior, justo después de los constructores / destructores.
Sjoerd
2

Es una decisión judicial para mí. Uso regiones cuando son necesarias para facilitar la lectura.

También uso un color diferente en mi combinación de colores de Visual Studio (actualmente un rojo oscuro) para que se destaquen del resto del código.


Un ejemplo de dónde podría usar una # región: si escribo un método de prueba para una prueba unitaria que requiere un fragmento de XML de varias líneas, la cadena XML romperá la sangría habitual (ya que comienza a lo largo del margen izquierdo de la ventana de código. Para ocultar la fealdad, la envolveré en una # región, para poder colapsarla.

Robert Harvey
fuente
2

El libro Clean Code de Bob Martin dedica todo el quinto capítulo al formateo. Hay un par de puntos clave que creo que lo resumen muy bien.

  • La mayoría de los intentos de agrupar variables y métodos por visibilidad y limpieza no tiene mucho sentido y hace que navegue mucho por el código.
  • Mantener métodos que se llaman verticalmente entre sí reduce la cantidad de navegación que necesita hacer y facilita la búsqueda de cosas.
  • Su línea de pensamiento no se romperá si tiene que detenerse y pensar "¿en qué región pertenece este código?" cada pocos minutos.
  • Las variables de instancia generalmente deben ser pocas, y probablemente se usen en todas partes, por lo tanto, pertenecen a la parte superior de la clase donde serán más fáciles de ubicar. Las variables y declaraciones que solo serán utilizadas por un método deben existir dentro de ese método. Si se usa solo con un par de métodos, entonces deben estar verticalmente cerca pero por encima de los pocos métodos que los están usando.

Mantener su código organizado con elementos que interactúan comúnmente verticalmente juntos de manera efectiva elimina cualquier necesidad de crear regiones específicas. Si su código es tan largo que requiere que las regiones oculten mucho código, entonces quizás sea un olor a código que indica que la clase está tratando de hacer demasiado. Quizás parte de la funcionalidad se pueda trasladar a una clase de utilidad o subir a un antepasado.

Si necesita "ocultar" el código porque es demasiado largo o demasiado "feo", entonces probablemente tenga mayores problemas de los que preocuparse que si usar o no las regiones. Personalmente, nunca necesito usarlos, y cuando trabajo en el código de otra persona, siempre necesito abrirlos todos, así que ¿por qué molestarse?

S.Robins
fuente
1
+1 - Me sorprende que esto no se haya mencionado de manera más prominente. El principio de cohesión también se aplica a cómo distribuye su código, y la agrupación por modificador de acceso es (la mayoría de las veces) contraproducente.
Daniel B
0

Actualmente diseño clases como esta:

class types
constructors
destructor
accessors
methods
properties (where properties are present in the language)
member variables

y luego prefije el nivel de acceso a cada declaración (más o menos, a veces agrupar por acceso). Solía ​​agrupar a nivel superior por acceso, pero en algún momento, no sé cuándo, no funcionó tan bien como lo anterior. Por ejemplo, en C ++ / CLI (que estoy obligado a usar en este momento :-() puede hacer esto, lo que desordena la agrupación por acceso:

public: property int SomeProperty
{
private: void set (int value) { ... }
public: int get () { ... }
}
Skizz
fuente
¿Qué son los "miembros" en la parte inferior? Para mí, ese es un término general para todas las piezas de una clase.
Mason Wheeler
@Mason: deben ser "variables miembro" para evitar confusiones.
Skizz
Realmente no consigo agrupar cosas por tipo como ese. ¿Cuál es la diferencia entre un método y una propiedad realmente? Nunca he ido a buscar las propiedades de una clase, sin embargo, buscaré código relacionado lógicamente, ya sean propiedades, métodos, lo que sea.
Ed S.
0

Respuesta marginal: no, al menos cuando se trata de C #. Entre Visual Studio y R # puedo navegar mágicamente a cualquier miembro o implementación, por lo que no tiene sentido obsesionarse con esto; simplemente comienza a escribir donde está el cursor.

Wyatt Barnett
fuente
0

Al igual que Wyatt y otras respuestas, generalmente también evito el uso de regiones. Las regiones tienen un propósito; para ocultar el código que no quieres tener que mirar. Si tiene mucho código en una clase que no desea tener que mirar y, por lo tanto, necesita muchas regiones que le permitan colapsar dicho código, entonces probablemente tenga demasiado código en la clase. ReSharper no respeta las regiones al decidir dónde colocar el nuevo código, a menos que haya creado la región (lo que hace para implementaciones de interfaz).

El único uso de las regiones que considero aceptable es ocultar el código "inevitablemente feo"; código que trata con detalles de implementación específicos que no pueden ser bien diseñados internamente según los estándares actuales. Por lo general, este es un código esotérico avanzado que, en general, no debe ser molestado por el programador junior promedio una vez escrito. Estas son cosas como:

  • Ciertas implementaciones de interfaz incorporadas (IDisposable, IConvertible, a veces IEnumerable o IComparable, ya que requieren implementaciones genéricas y no genéricas)
  • Incrustado P / Invocar externos y estructuras relacionadas.
  • Finalizadores / destructores (generalmente va con IDisposable)
  • Se conecta a la memoria no administrada / punteros / código "inseguro".
KeithS
fuente