Por que a herança de forma deve ser evitada?

9

Lembro-me de aprender VB4 e arrastar um botão para um formulário, clicar duas vezes nesse botão e digitar o código no manipulador de eventos com o qual eu havia sido magicamente abençoado. Vindo do QBASIC, fiquei emocionado com o "V" em "VB", o designer visual era literalmente a melhor coisa desde o pão fatiado.

É claro que você poderia fazer tudo isso de forma programática, mas a magia do "V" era tão atraente que você não podia deixar de arrastar esse botão. Fomos encorajados a seguir esse caminho.

Mas, há alguns anos, comecei a aprender sobre C # e a estrutura .net e fiquei fascinado com a maneira como tudo o que eu pensava que sabia sabia acabara de sair pela janela. Há muita mágica acontecendo no VB6 que é completamente revelada no .net: considere os construtores e o InitializeComponentsmétodo, por exemplo. Neste último, você encontrará todas as instâncias de controle que você arrastou da caixa de ferramentas, todos os eventos que você registrou e as propriedades que definiu no designer.

E tudo bem ... eu acho. É que, sinto que não sou o dono do que está acontecendo, esse código que só posso modificar através do designer me incomoda. Toda vez que você copia um botão que diz "Ok" de um formulário para outro (às vezes junto com o irmão "Cancel"), na verdade você está duplicando o código, e isso é pecado, não é? SECA, não se repita, diz o papa .

Religiões e escolas de pensamento à parte, com toda objetividade, não deveríamos derivar formas de formas básicas e deixar o botão "Ok" (e todos os seus amigos) viver na forma base? Algo como a FormBasedo qual deriva a DialogFormBase; todas as classes criadas em pouco tempo ... digitando código. Os botões são criados dependendo de como a classe é instanciada (isto é, um argumento enum do construtor determina quais botões devem ser criados), os controles são definidos dentro de um arranjo de painéis divididos e painéis de layout de fluxo, injetados no formulário comoContentque se encaixa no painel de conteúdo principal. Não é isso que o ASP.net faz com páginas mestras e espaços reservados para conteúdo? Eu derivaria um formulário quando precisar de uma nova "página mestre", mas essa nova "página mestre" ainda deriva de uma classe de formulário base, para que os visuais sejam consistentes em todo o aplicativo.

Para mim, é muito mais reutilização de código do que qualquer outra coisa que já fiz com o designer no WinForms, e nem foi difícil, e o código não é confuso com um método de 200 linhas que não tenho controle, posso colocar comentários onde eu quiser, eles não serão substituídos por um designer. Eu acho que é apenas uma questão de padrões e arquitetura, que foi o que me levou a este link: Melhor design para formulários do Windows que compartilham funcionalidades comuns , onde eu percebi que estava no local, exceto a resposta, sugere exatamente o que eu sou mas aconselha contra a herança de formulários devido a considerações do designer. Essa é a parte que eu não entendo .por causa de considerações de estrutura de código, especialmente no que diz respeito à herança de forma e controle, que não vejo outra razão para evitar além de quebrar o designer .

Não podemos todos ser apenas preguiçosos, então que parte estou perdendo?

Mathieu Guindon
fonte
Eu não entendo Você está sugerindo que não devemos usar designers visuais e escrever todos os códigos da GUI manualmente?
Euphoric
Antes do .NET, onde estava o código que controlava todos os objetos arrastados no formulário?
JeffO 24/03
11
@JeffO, a julgar pelo código legado com o qual lidei, diria no formulário, em algum lugar entre SQL in-line ad-hoc e lógica de negócios. O ponto é que o WinForms é .net; por isso, se o designer está trabalhando bem com o que hoje em dia cheira a "código ruim" e "maus hábitos de codificação" e realmente quebra quando você começa a estruturar as coisas, digo que largue o designer e trate as formas como elas são (classes!) .. e como a codificação de uma camada de interface do usuário no C # é tão diferente de codificar uma camada de interface do usuário no ExtJS? É "tedioso" fazer isso no WinForms porque "olha, tem um designer"? A codificação de uma interface do usuário ExtJS é tediosa?
Mathieu Guindon 24/03
Vou citar outro usuário: CodeCaster; Um manipulador de eventos destina-se a conectar a GUI à sua lógica de negócios. Se você tiver uma caixa de texto para inserir o nome de um usuário e um botão Adicionar, clique no botão Adicionar apenas para chamar _userRepository.AddUser (UsernameTextbox.Text). Você não deseja lógica de negócios em manipuladores de eventos. stackoverflow.com/questions/8048196/…
Pieter B
@ Pieter não coloca uma dependência de DAL em sua camada de apresentação?
Mathieu Guindon 25/03

Respostas:

9

Vou me opor a você com um paradigma diferente: favorecer a composição sobre a herança.

Mesmo quando você começa a escrever o código da GUI manualmente e usa a herança para compartilhar comportamentos e recursos visuais entre formulários, o mesmo problema ocorre no design normal de OOP. Digamos que você tenha o DialogForm, que possui botões OK / Cancelar, e o GridForm, que possui grade. Você obtém todas as caixas de diálogo do DialogForm e todos os formulários com o Grid do GridForm. E então você descobre que deseja o formulário com ambos. Como você resolveria isso? Se você estiver usando a herança de formulário, não há como resolvê-lo. Por outro lado, se você estiver usando UserControls, basta colocar o GridControl no seu formulário e concluir o processo. E você ainda pode usar o designer com UserControls, para não perder tempo escrevendo código GUI tedioso.

Eufórico
fonte
Bem, o formulário base apenas possui um SplitContainer com Panel2 fixo, contendo um FlowLayoutPanel chamado BottomPanele hospedando os comportamentos comuns Ok / Cancel / Apply / Close; O Panel1 contém um SplitContainer com o Panel1 fixo (para hospedar rótulos comuns de "instruções", ou menus, barras de ferramentas, o que estiver na parte superior) e o Panel2 segurando um Painel protegido chamado MainContent; cada implementação real decide como preenchê-la. Todo o conteúdo pode ser injetado na implementação e, sim, esse pode ser um controle de usuário feito com o designer para economizar tempo, bom ponto ... mas e o próprio formulário?
Mathieu Guindon 23/03
O problema aqui é escala. Quando você solicita 10 formulários, ter um formulário comum único não é grande coisa. Os problemas começam quando você tem um aplicativo com dezenas ou centenas de formulários. Em seguida, você terá formulários com partes comuns, mas nunca o suficiente para criar o formulário base. No seu caso, pode ser que você queira usar um layout ou botões diferentes, mas mantenha tudo o mesmo. E é aí que os problemas começam.
Euphoric
2
O 'problema com escala "não existe se você tiver um design meio decente. Temos um projeto em que trabalho com algumas centenas de formulários. Usamos a herança de formulários fortemente para fornecer consistência e funcionalidade comum, e nunca tivemos problemas com ele.
Mason Wheeler
2
@MasonWheeler Eu tive uma experiência exatamente oposta. Tentamos usar a herança de formulários em um de nossos aplicativos, e toda vez que fazíamos pouca alteração nos formulários base, tudo se deteriorava e tivemos que corrigir manualmente todos os outros formulários. Além disso, o designer se comporta de maneira estranha quando você trabalha com a forma herdada.
Euphoric
11
@Euphoric: Qual designer? Usamos o Delphi, e seu designer funciona bem com formulários herdados. E, novamente, você não tem esses problemas se tiver um bom design . Se você não planeja nada, é claro que tudo ficará quebradiço e quebrará sempre que você tocar, mas isso não é diferente de qualquer outro código.
Mason Wheeler
2

Muito disso está atrelado à pilha de tecnologia escolhida.

O WinForms e o WPF podem ser estruturas de interface do usuário do .NET, mas variam muito em como você alcança o objetivo final. Certos paradigmas se movem entre as tecnologias muito bem, mas outros não, e você não deve tentar forçar um paradigma simplesmente porque sente que ele deve existir em todas as estruturas. Há uma razão pela qual o MVVM é voltado para o WPF / SL e o MVC é um conceito separado no ASP.NET do WebForms e assim por diante. Certas tecnologias funcionam melhor com certos paradigmas.

Lembre-se de que o código gerado geralmente deve ser removido de suas preocupações com o DRY. Embora aplicável em alguns casos, na maioria das vezes deve ser ignorado. Os conceitos DRY certamente devem permanecer um foco fora da camada de apresentação, mas na camada de apresentação o código gerado é mais frequentemente um subproduto da estrutura em que você está trabalhando. Isso não significa que você não pode aplicar os princípios DRY em sua abordagem, mas permanece cauteloso. Você poderia criar um formulário base e herdá-lo indefinidamente? Sim. Você pode arrastar e soltar componentes em um novo formulário sempre que necessário? Sim. Mantenha o foco no objetivo final, evitando possíveis defeitos, facilitando a refatoração a jusante e a escalabilidade enquanto trabalha dentro dos limites da pilha de tecnologia de sua escolha.

Aaron McIver
fonte
0

Você pode usar a herança, desde que encapsule corretamente seus campos e preencha adequadamente. Se você estava interessado em usar a herança, minha sugestão seria ter a forma base e um modelo correspondente para essa forma, e para cada derivação derivar a forma e o modelo.

Uma alternativa muito melhor seria agrupar controles relacionados em um ou mais controles UserControl. Você só precisa de um pouco de lógica para inserir os dados relevantes.

Sam
fonte
0

Eu concordo totalmente com Mason Wheeler, embora em três anos talvez até ele próprio tenha mudado de idéia.

Estou tentando procurar alternativas para migrar dos executáveis ​​do Delphi para a WEB.

Até agora eu me decidi pela UNIGUI, porque ainda posso usar a herança de formulário. Eu gostaria que o Delphi tivesse Mixins como o Dart, pois isso me permitiria ter menos ancestrais. Mas sinto que as pessoas escrevem muito mais código no MVC do que com o Visual Form Herança, já que a maior parte da navegação chama as regras de validação no datamodule (applyupdates), critérios de filtragem sql, pesquisando o conjunto de dados do cliente, tudo está escrito em 5 talvez 6 Formar ancestrais.

Mesmo o "Com o MVC será mais fácil para você deixar o Delphi no recurso" para mim não funciona como argumento, já que as pessoas convidaram o OOP, tudo são classes, propriedades, métodos. Então, tudo que eu preciso é de um tradutor. Realmente não foi possível encontrar nenhuma vantagem, talvez para sites muito menos complicados, mas que mudam diariamente.

user3145857
fonte