Como você normalmente organiza as regiões de uma classe?

17

Fiquei me perguntando se havia um padrão para definir as regiões de uma classe.

Atualmente uso

Fields
Constructor
Properties
Public Methods
Private Methods

Fieldssendo propriedades privadas e Propertiespúblicas. Normalmente, utilizarei sub-regiões nesse caso, se necessário, ou ocasionalmente adicionarei outras regiões abaixo (como membros da interface ou baseClass).

Rachel
fonte
1
Você está falando sobre layout em geral ou usando "#regions"?
precisa saber é o seguinte
1
@snmcdonald eu uso #regiontags para definir uma seção
Rachel
Isso não deveria ser uma pergunta do wiki da comunidade? Não acredito que exista um padrão, e a resposta pode mudar dependendo dos idiomas.
#
7
Eu começo excluindo todos os #regions
Ed S.
3
@ Ed S. +1 porque as regiões são o diabo. Tudo o que eles permitem é obscurecer o fato de que seu arquivo de código é muito grande e precisa ser refatorado.
MattDavey

Respostas:

4

Enums relacionadas à classe ou ocasionalmente estruturas / classes de dados puros (acima da definição de classe real)

--- Definição de classe ---

Membros privados

CTORs / DTORs se o idioma tiver DTORs

Propriedades públicas

Métodos de utilidade (métodos privados ou protegidos com escopo pequeno)

Funcionalidade de classe (pode ser dividida em várias regiões, dependendo do escopo da classe).

Pax Noctis
fonte
17

Sub-regiões? Sua turma tem uma única responsabilidade ? (implícito nisso ... minha resposta é "Raramente qualquer região, exceto talvez agrupar propriedades, construtores e métodos" ... mas, mesmo assim, eu não o uso muito)

MIA
fonte
2
Estou programando no WPF agora e um exemplo de algumas sub-regiões que eu usaria é um ViewModel que tem suas propriedades públicas divididas em propriedades relacionadas à interface do usuário, comandos, dados etc. Isso facilita muito a localização do que eu sou. procurando rapidamente
Rachel
2
Por que não usar grandes banners de comentários em vez de regiões? // ----------ViewModel Properties---------- Dessa forma, você ainda pode ver o código (ou reduzi-lo com o esboço e ver os membros). As regiões são para esconder coisas. O código não deve ser oculto, a menos que seja gerado automaticamente ou algo assim.
precisa saber é o seguinte
1
@ Rachel favorecer a composição.
MattDavey
10

Eu só queria confirmar que você quis dizer "#regions" e não o layout da classe em geral.

Estou surpreso que ninguém tenha mencionado para evitar o uso de regiões. Entendo que o OP quer fazer uma pesquisa sobre a definição de regiões, mas gostaria de levantar um ponto de vista alternativo.

Eu evito regiões. Eu gosto de ver o código com o qual estou trabalhando. Se você achar difícil encontrar o que está procurando, use a dobragem de código e agrupe construções de classe semelhantes.

Por que odeio regiões? CTRL+M,Le CTRL+M,Oalternará a dobra de código. No entanto, ao recolher, oculta toda a região. Eu só preciso recolher métodos / propriedades / comentários.

Se houver muitas regiões, talvez seja um cheiro de código e sua classe esteja fazendo muito trabalho. Jeff Atwood fornece um bom post sobre regiões que valem a pena ser lidas.

Minha citação favorita em #regions:

Não, não usarei #regions. E não, NÃO NEGOCIO COM TERRORISTAS. Cale-se.

- Jeff Atwood

Dito isto, sei que muitos programadores insistem em usá-los. Esta questão é subjetiva. Eu apenas pensei em oferecer uma alternativa.

snmcdonald
fonte
1
Aqui está uma macro para recolher as definições, mas expandir as regiões, caso você esteja preso trabalhando com pessoas apaixonadas por regiões: stackoverflow.com/questions/523220/awesome-visual-studio-macros/… Funciona bem, a menos que você trabalhando com pessoas realmente doentes que colocam regiões dentro de métodos .
precisa saber é o seguinte
Uma macro muito útil! Não sei por que eles não o criaram no visual studio, no entanto, obrigado.
snmcdonald
Meu chefe ama regiões, as ama. Ele também ama classes internas privadas e métodos enormes. Nosso código tem uma classe com cerca de uma dúzia de regiões dividindo-a, três classes internas e alguns métodos, desde que tenham uma dúzia de regiões de nível superior, com sub-regiões dentro delas.
CodexArcanum 29/03
4

Varia de idioma para idioma. Como sou um codificador Delphi, tenho a tendência de seguir a convenção padrão Delphi, que se parece com isso:

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;

Acho uma boa maneira de organizar informações fáceis de ler e entender.

Mason Wheeler
fonte
3
Acho incrível que privado, protegido, público e publicado sejam ordenados alfabeticamente e encapsuladamente e todos eles começam com P!
Peter Turner #
divertido, eu não. Sempre achei que era mais natural listar publicprimeiro, já que a maioria dos usuários se importa apenas com as publiccoisas.
Matthieu M.
Eu sempre achei essa convenção uma ideia muito boba. O que a visibilidade tem a ver com a funcionalidade? Em qualquer caso, eu sempre usei Interfaces para definir a funcionalidade pública, mas implementei a Interface como protegida na classe. Os únicos itens que agruparei consistentemente são métodos e propriedades Publicados para componentes e, caso contrário, sempre agrupo por Interfaces e herança, usando várias palavras-chave de visibilidade, conforme necessário. Os itens exclusivos da implementação da classe (ie: não substituições) devem realmente ser listados primeiro.
31512 S.Robins
3

Costumo colocá-los da seguinte maneira:

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

Não usei um idioma que use Properties, é por isso que eles não são definidos. Coloquei métodos e campos privados na parte inferior, porque se alguém mais estiver usando esse arquivo em seu código, ele só precisará se preocupar com a API, que é o material público. E todos os editores de texto que eu conheço, e até IDEs, posicionam o cursor na parte superior ao abrir arquivos.

gablin
fonte
+1 para colocar campos privados na parte inferior. Agrupo métodos públicos pela interface que eles implementam e coloco aqueles que não implementam nenhuma interface no topo, logo após os construtores / destruidores.
Sjoerd
2

É um julgamento para mim. Eu uso regiões quando elas são necessárias para facilitar a leitura.

Também uso uma cor diferente no esquema de cores do Visual Studio (atualmente vermelho escuro) para destacá-las do restante do código.


Um exemplo de onde eu poderia usar uma # região: Se eu escrever um método de teste para um teste de unidade que exija um trecho de código de XML com várias linhas, a sequência XML interromperá o recuo usual (uma vez que inicia na margem esquerda de Para ocultar a feiura, vou envolvê-la em uma região #, para que possa recolhê-la.

Robert Harvey
fonte
2

O livro Clean Code de Bob Martin dedica todo o quinto capítulo à formatação. Há alguns pontos-chave que considero resumir bem.

  • A maioria das tentativas de agrupar variáveis ​​e métodos por visibilidade e limpeza Não faz muito sentido e faz com que você navegue muito pelo código.
  • Manter os métodos que se chamam verticalmente próximos reduz a quantidade de navegação que você precisa fazer e facilita a localização de coisas.
  • Sua linha de pensamento não será interrompida se você precisar parar e pensar "em qual região esse código pertence?" a cada poucos minutos.
  • As variáveis ​​de instância geralmente devem ser poucas e provavelmente usadas em todos os lugares; portanto, elas pertencem ao topo da classe onde serão mais fáceis de localizar. Variáveis ​​e declarações que serão usadas apenas por um método precisam existir dentro desse método. Se usado por apenas alguns métodos, eles devem estar próximos verticalmente, mas acima dos poucos métodos que os estão usando.

Manter seu código organizado com elementos que interagem normalmente na vertical juntos efetivamente remove qualquer necessidade de criar regiões específicas. Se o seu código for tão longo que requer que as regiões ocultem muito código, talvez seja um cheiro de código indicando que a classe está tentando fazer muito. Talvez algumas das funcionalidades possam ser transferidas para uma classe de utilitário ou empurradas para um ancestral.

Se você precisar "ocultar" o código por ser muito longo ou muito "feio", provavelmente terá problemas maiores com o que se preocupar do que usar ou não regiões. Pessoalmente, nunca preciso usá-los e, ao trabalhar no código de outra pessoa, acho que sempre preciso abri-la de qualquer maneira, então, por que se preocupar?

S.Robins
fonte
1
+1 - Estou surpreso que isso não tenha sido mencionado com mais destaque. O princípio da coesão também se aplica à forma como você define seu código, e o agrupamento por modificador de acesso é (na maioria das vezes) contraproducente.
Daniel B
0

Atualmente, layout classes como esta:

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

e prefixe o nível de acesso a cada declaração (meio que às vezes agrupe por acesso). Eu costumava fazer agrupamentos de nível superior por acesso, mas em algum momento, não sei quando, não funcionou tão bem quanto o descrito acima. Por exemplo, em C ++ / CLI (que sou forçado a usar no momento :-(), você pode fazer isso, o que atrapalha o agrupamento por acesso:

public: property int SomeProperty
{
private: void set (int value) { ... }
public: int get () { ... }
}
Skizz
fonte
O que são "membros" na parte inferior? Para mim, esse é um termo genérico para todas as partes da classe.
Mason Wheeler
@Mason: devem ser "variáveis ​​de membro" para evitar confusão.
Skizz 27/09
Eu realmente não consigo agrupar as coisas por tipo assim. Qual é a diferença entre um método e uma propriedade realmente? Nunca procurei as propriedades de uma classe; no entanto, procurarei código relacionado à lógica, sejam elas propriedades, métodos, o que for.
Ed
0

Resposta marginal lunática: Não, pelo menos quando se trata de C #. Entre o Visual Studio e o R #, posso navegar magicamente para qualquer membro ou implementação, para que não haja motivo algum para ficar obcecado com isso; basta começar a digitar onde está o cursor.

Wyatt Barnett
fonte
0

Como Wyatt e algumas outras respostas, também geralmente evito o uso de regiões. As regiões têm um propósito; para ocultar o código que você não deseja ver. Se você tem muito código em uma classe que não deseja ver, e portanto precisa de muitas regiões para permitir o recolhimento do código, provavelmente terá muito código na classe. O ReSharper não respeita as regiões ao decidir onde colocar o novo código, a menos que tenha criado a região (o que faz para implementações de interface).

O único uso das regiões que considero aceitáveis ​​é ocultar o código "inevitavelmente feio"; código que lida com detalhes de implementação específicos que não podem ser bem arquitetados internamente para os padrões atuais. Geralmente, é um código esotérico avançado que geralmente não deve ser confundido com o programador júnior comum, uma vez escrito. São coisas como:

  • Certas implementações de interface internas (IDisposable, IConvertible, às vezes IEnumerable ou IComparable, pois exigem implementações genéricas e não genéricas)
  • P / Invocar externos e estruturas relacionadas.
  • Finalizadores / destruidores (geralmente acompanha IDisposable)
  • Conecta-se à memória não gerenciada / ponteiros / código "inseguro".
KeithS
fonte