ti-enxame.com

Como você normalmente faz o layout das regiões de uma classe?

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

Eu atualmente uso

Fields
Constructor
Properties
Public Methods
Private Methods

Fields sendo Propriedades Privadas e Properties sendo as públicas. Normalmente, usarei sub-regiões dentro dela, se necessário, ou ocasionalmente adicionarei outras regiões abaixo (como membros de interface ou baseClass).

17
Rachel

Enums relacionados à classe ou ocasionalmente classes structs/pure-data (acima da definição real da classe)

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

Membros privados

CTORs/DTORs se o idioma tiver DTORs

Propriedades públicas

Métodos utilitários (métodos privados ou protegidos com escopo pequeno)

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

4
Pax Noctis

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

17
MIA

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 deseja fazer uma votação sobre o layout de regiões, mas gostaria de levantar um ponto de vista alternativo.

Eu evito regiões. 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 classes semelhantes.

Por que eu odeio regiões? CTRL+M,LCTRL+M,O irá alternar o dobramento de código. No entanto, ao recolhê-lo 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 uma boa postagem sobre regiões que vale a pena ler.

Minha citação favorita em #regions:

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

- Jeff Atwood

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

10
snmcdonald

Isso varia de idioma para idioma. Como sou um programador Delphi, tendo a seguir a convenção padrão Delphi, que se parece com isto:

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 que é uma boa maneira de organizar informações fáceis de ler e entender.

4
Mason Wheeler

Eu costumo colocá-los da seguinte maneira:

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

Não usei uma linguagem que use Properties então é por isso que eles não estão dispostos. Eu coloquei métodos e campos privados na parte inferior porque se outra pessoa estiver usando esse arquivo em seu código, ela deve apenas se preocupar com a API, que é o material público. E todos os editores de texto que conheço, e até mesmo IDEs, colocam o cursor no topo ao abrir arquivos.

3
gablin

O livro Código Limpo de Bob Martin dedica todo o 5º capítulo à formatação. Há alguns pontos-chave que acho que resumem 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 métodos que chamam uns aos outros verticalmente próximos reduz a quantidade de navegação que você precisa fazer e torna mais fácil encontrar coisas.
  • Sua linha de pensamento não será interrompida se você tiver que parar e pensar "a que região pertence este pedaço de código?" a cada poucos minutos.
  • Normalmente, as variáveis ​​de instância devem ser poucas e provavelmente serão usadas em qualquer lugar, portanto, 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 usados ​​por apenas alguns métodos, eles devem estar verticalmente próximos, mas acima dos poucos métodos que os usam.

Manter seu código organizado com elementos de interação comum verticalmente próximos uns dos outros efetivamente remove qualquer necessidade de criar regiões específicas. Se o seu código for tão longo que requer regiões para ocultar uma grande quantidade de código, talvez seja um cheiro de código indicando que a classe está tentando fazer muito. Talvez algumas das funcionalidades possam ser movidas para uma classe de utilitário ou empurradas para um ancestral.

Se você precisa "ocultar" o código porque ele é muito longo ou muito "feio", então provavelmente você tem problemas maiores com 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-los todos de qualquer maneira, então por que me preocupar?

2
S.Robins

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

Também uso uma cor diferente em meu esquema de cores do Visual Studio (atualmente um vermelho escuro) para destacá-los do resto do código.


Um exemplo de onde eu poderia usar um #region: se eu escrever um método de teste para um teste de unidade que requer um fragmento de várias linhas de XML, a string XML quebrará o recuo usual (uma vez que começa ao longo da margem esquerda de a janela de código. Para esconder a feiura, vou envolvê-la em uma #region, para poder recolhê-la.

2
Robert Harvey

Atualmente, faço o layout de classes como esta:

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

e, em seguida, prefixe o nível de acesso para cada declaração (espécie de, às vezes agrupar por acesso). Eu costumava fazer agrupamento de nível superior por acesso, mas em algum momento, não sei quando, não funcionou tão bem quanto o anterior. 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 () { ... }
}
0
Skizz

Como Wyatt e algumas outras respostas, geralmente também evito o uso de regiões. As regiões têm um propósito; para ocultar o código que você não deseja examinar. Se você tem muito código em uma classe que não deseja examinar e, portanto, precisa de muitas regiões para permitir o recolhimento desse código, provavelmente você tem código demais na classe. ReSharper não respeita 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ável é 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. Este é geralmente um código avançado e esotérico que geralmente não deve ser confundido pelo programador júnior médio, uma vez escrito. São coisas como:

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

Resposta 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, portanto, não há motivo para ficar obcecado com essas coisas; basta começar a digitar onde está o cursor.

0
Wyatt Barnett