Fórum Qual a melhor forma de aplicar OO a um projeto? #11236

06/11/2009

0

Amigos,

Gostaria de algumas indicações de como melhor estruturar um projeto com OO.

Eu já utilizo LINQ 2 Entities no projeto.
É meu primeiro projeto, e portanto surgem muitas dúvidas.
A maior delas:

Como aplicar OO em todo o projeto?

Eu estou com muita coisa amarrada dentro dos forms, mais precisamente dentro dos eventos...Essa parece a antiga metodologia de programação dos sistemas em DELPHI, onde se programava orientado a eventos.

Eu tento ao máximo não amarrar nada no form, mas quando menos espero estou cheio de regras de negócio dentro do botão!!

Primeiro eu vou e crio um método pra essa regra de negócio, porém dentro do form mesmo (o form é uma classe).

Eu fico com aquele martelinho na cabeça (aplicar OO, colocar em classes), vou lá, retiro o método do form e colo ele na classe. Acaba sendo útil que eu reuso em alguns lugares, mas nada muito genérico, pois o método veio de uma regra de negócio que estava específica pra um form.


Resumindo,

Como aplicar OO pra ela me ser 100% útil no projeto (e não fazer um software orientado a eventos e apenas retirar o método do form e colar na classe!)
Daniel Vieira

Daniel Vieira

Responder

Posts

09/11/2009

Fabio Mans

Olá André procure estudar Padrões de Projeto, um bom livro é o Use a Cabeça - Padrões de Projeto, com um bom entendimento de POO e padrões de projeto com certeza esta sua dúvida irá diminuir.   http://www.submarino.com.br/produto/1/1138065/use+a+cabeca!:+padroes+de+projetos+(design+patterns)   Uma outra coisa que acho legal é você montar um Framework com métodos que você mais utiliza, por exemplo um DataBaseHelper, uma classe de envio de email, outra de criptografia, mantenha estes códigos em um projeto a parte e com certeza você irá escrever menos. Um outro caminho é estudar Arquitetura.  Acompanhe o fórum abaixo.   http://social.msdn.microsoft.com/Forums/pt-BR/arquiteturapt/threads   Neste Fórum existem muitas discussões sobre projetos em camada e como utilizar. Mas garanto para você, mesmo programadores que já programam a um bom tempo (POO)  tem está mesma dúvida que você.   Sua dúvida não é simples e podemos ficar conversando várias horas sobre estes assuntos e é um tópico que me interesse muito e vamos mantendo contato.   Espero ter ajudado.   Fabio.        
Responder

Gostei + 0

09/11/2009

Daniel Vieira

Conversando com minha namorada, que recentemente começou a estagiar em uma empresa de desenvolvimento, ela me contou que a lógica de negócio fica encapsulada em um arquivo .pas (do delphi), que é chamado externamente no ASP.NET
Eu queria chegar nesse nível, ter um arquivo de lógica separado da minha aplicação, e ter no form somente os campinhos, a validação de enable, visible etc...

Mas não consigo chegar nesse nível.
Quando eu vejo meu form está lotado de lógicas, apenas algumas instancias bobas como uma que me devolve um select.

Um dos motivos disso é que o sistema começou meio que Estruturado, pois nosso analista é desenvolvedor Clipper, OO pra ele é meio complicada...Ele se baseia na base de dados, DER e no DFD (nada contra) mas não temos nenhuma modelagem UML, portanto nenhuma classe específica, apenas as que eu crio (que normalmente são as tabelas, e nem precisaria muito, porque as tabelas o linq cria classes pra mim!)

Única coisa que eu consegui abstrair do projeto, colocando em outro projeto, foi a padronização de alguns componentes básicos, como o form padrão (apenas tamanho, cor e etc) botão e label.

Gostaria de acertar o projeto agora no início, porque depois acaba virando uma bola de neve enorme, você não consegue parar pra reacertar o que está problemático, e não consegue dar continuidade da maneira correta, pois o projeto começou "torto".

Tenho alguns prazos, e a empresa que trabalho só vê a parte funcional, está funcionando OK, estou cadastrando então está ótimo (trabalho pro usuário final e não em uma Softwarehouse)

Se não acertar o projeto rapidamente, estaremos contratando outro programador dentro em breve, e se ele pegar o negócio desandado a coisa pode ir de mal a pior!
Responder

Gostei + 0

09/11/2009

Fabio Mans

Por que não separa em camadas? Se puder criar uns projetos sem o Linq só para estudar você terá uma boa noção, geralmente fazemos as camadas utilizando as propriedades e atributos em uma camada, em outra o acesso a dados e a regra de negócio em outra, por fim o projeto Web ou Windows.   Na camada de negócios você irá validar suas regras, na de acesso a dados irá fazer as chamadas ao banco. É uma opção para que você não programe tudo na interface.       Fabio
Responder

Gostei + 0

09/11/2009

Daniel Vieira

Era exatamente isso que eu gostaria de fazer.

Mas nunca sequer vi um projeto assim!

Aqui no DevMedia tem algum curso correspondente?
Preferencia Free pra quem for assinante .NET magazine!


Eu tento separar o projeto, mas fica cada vez mais difícil, estou sempre amarrado na aplicação!
Responder

Gostei + 0

09/11/2009

Daniel Vieira

So pra visualizacao, da uma olhada em um corpo de form, o que eu estou trabalhando atualmente!
Olha o tamanho da brincadeira!
Eu queria ter form com 2 paginas, 90 linhas, não com  500 linhas e mais de 10 paginas de código!


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.Linq;
using System.Linq;
using System.Diagnostics;
using Materiais.Classes;


namespace Materiais.Forms
{
    public partial class frmReorganizacaoProduto : ConstrusysControl.Forms.Padrao
    {  
        public frmReorganizacaoProduto()
        {
            InitializeComponent();
        }

        private void btnCalendario_Click(object sender, EventArgs e)
        {
            //Exibir um form Calendario
            frmCalendar calendar = new frmCalendar();
            calendar.Show();
        }

        private void btnCalculadora_Click(object sender, EventArgs e)
        {
            //Exibe uma calculadora do Windows
            Process.Start("calc.exe");
        }

        private void btnSair_Click(object sender, EventArgs e)
        {
            //Fecha o form
            if (MessageBox.Show("Deseja realmente SAIR da tela?",
                                "CadastroGrupoSub",
                                MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                Dispose();
            }
            else
            {
                //cmbGrupo.Focus();
            }
        }

        private void frmReorganizacaoProduto_Load(object sender, EventArgs e)
        {
           
            //this.produtoTableAdapter.Fill(this.cONSTRUSYSDataSet271009.Produto);
           
            PreencheCmbGrupoDe();
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            string mensagemCodigos = montaMensagemTransferir();

            if (((int)cmbGrupoPara.SelectedValue == (int)cmbGrupoDe.SelectedValue) &&
               ((int)cmbGrupoSubPara.SelectedValue == (int)cmbGrupoSubDe.SelectedValue) &&
               ((int)cmbGrupoSubFamiliaPara.SelectedValue == (int)cmbGrupoSubFamiliaDe.SelectedValue))
            {
                MessageBox.Show("Origem e Destino são iguais, favor verificar");
                cmbGrupoDe.Focus();
            }
            else
            {

                if (MessageBox.Show(mensagemCodigos, "Transferencia de Produtos", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    try
                    {
                        int codGrupo = (int)cmbGrupoPara.SelectedValue;
                        int codGrupoSub = (int)cmbGrupoSubPara.SelectedValue;
                        int codGrupoSubFamilia = (int)cmbGrupoSubFamiliaPara.SelectedValue;

                        List<int> codigosSelecionados = new List<int>();

                        foreach (DataGridViewRow row in this.grdProdutoDe.Rows)
                        {
                            if (row.Cells["chkProdutoDe"].Value != null && Convert.ToBoolean(row.Cells["chkProdutoDe"].Value))
                                codigosSelecionados.Add(Convert.ToInt32(row.Cells["codigoProdutoDe"].Value));
                        }
                        TransfereCodigos(codGrupo, codGrupoSub, codGrupoSubFamilia, codigosSelecionados);
                        AtualizaGrdProdutoDe((int)cmbGrupoDe.SelectedValue,
                                            (int)cmbGrupoSubDe.SelectedValue,
                                            (int)cmbGrupoSubFamiliaDe.SelectedValue);
                        AtualizaGrdProdutoPara(codGrupo, codGrupoSub, codGrupoSubFamilia);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Selecione todos os campos\n" + ex.Message);
                        cmbGrupoDe.Focus();
                    }
                }
                else
                {
                    cmbGrupoDe.Focus();
                }
            }
        }

        private string montaMensagemTransferir()
        {
            string mensagemCodigos = "";
            string codGrupoDe = cmbGrupoDe.Text;
            string codGrupoSubDe = cmbGrupoSubDe.Text;
            string codGrupoSubFamiliaDe = cmbGrupoSubFamiliaDe.Text;
            string codGrupoPara = cmbGrupoPara.Text;
            string codGrupoSubPara = cmbGrupoSubPara.Text;
            string codGrupoSubFamiliaPara = cmbGrupoSubFamiliaPara.Text;

            int maior = 0;

            maior = codGrupoDe.Length;
            if (codGrupoSubDe.Length > maior)
                maior = codGrupoSubDe.Length;
            if (codGrupoSubFamiliaDe.Length > maior)
                maior = codGrupoSubFamiliaDe.Length;

            while (maior > codGrupoDe.Length)
                codGrupoDe = codGrupoDe + " ";

            while (maior > codGrupoSubDe.Length)
                codGrupoSubDe = codGrupoSubDe + " ";

            while (maior > codGrupoSubFamiliaDe.Length)
                codGrupoSubFamiliaDe = codGrupoSubFamiliaDe + " ";


            mensagemCodigos = "Deseja Realmente transferir de\n\n" +
                              "---\n" +
                              codGrupoDe + "    >>    " + codGrupoPara + "\n" +
                              codGrupoSubDe + "    >>    " + codGrupoSubPara + "\n" +
                              codGrupoSubFamiliaDe + "    >>    " + codGrupoSubFamiliaPara;
            return mensagemCodigos;
        }

        /*private void btnTransferir_Click(object sender, EventArgs e)
        {
            /*foreach (DataGridViewRow row in this.grdProdutoDe.Rows)
            {
                if (Convert.ToBoolean(row.Cells["chkProdutoDe"].Value))
                    MessageBox.Show(row.Cells["descricaoProdutoDe"].Value.ToString());
            }

            foreach (DataGridViewRow row in this.grdProdutoDe.Rows)
            {
                row.Cells["chkProdutoDe"].Value = true;
                   
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in this.grdProdutoDe.Rows)
            {
                row.Cells["chkProdutoDe"].Value = false;

            }
        }*/

        private void cmbGrupoSubDe_DropDownClosed(object sender, EventArgs e)
        {
            cmbGrupoSubFamiliaDe.Enabled = true;
            PreencheCmbGrupoSubFamiliaDe();
            if (cmbGrupoSubFamiliaDe.Enabled)
            {               
                AtualizaGrdProdutoDe(Convert.ToInt32(cmbGrupoDe.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubDe.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubFamiliaDe.SelectedValue));
            }
        }

        private void cmbGrupoSubFamiliaDe_DropDownClosed(object sender, EventArgs e)
        {
            AtualizaGrdProdutoDe(Convert.ToInt32(cmbGrupoDe.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubDe.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubFamiliaDe.SelectedValue));

            cmbGrupoPara.Enabled = true;
           
        }

        private void cmbGrupoPara_DropDownClosed(object sender, EventArgs e)
        {
            cmbGrupoSubPara.Enabled = true;
            PreencheCmbGrupoSubPara();
            if(cmbGrupoSubFamiliaPara.Enabled)
                PreencheCmbGrupoSubFamiliaPara();
        }

        private void cmbGrupoSubPara_DropDownClosed(object sender, EventArgs e)
        {
            cmbGrupoSubFamiliaPara.Enabled = true;
            PreencheCmbGrupoSubFamiliaPara();
        }

        private void cmbGrupoSubFamiliaPara_DropDownClosed(object sender, EventArgs e)
        {
            AtualizaGrdProdutoPara(Convert.ToInt32(cmbGrupoPara.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubPara.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubFamiliaPara.SelectedValue));

            btnOk.Enabled = true;
        }

        private void PreencheCmbGrupoDe()
        {
            var grupo = ClassGrupo.GetGrupoDescID();

            cmbGrupoDe.DataSource = grupo;
            foreach (var item in grupo)
            {
                cmbGrupoDe.DisplayMember = "Descricao";
                cmbGrupoDe.ValueMember = "ID";
            }
        }

        private void PreencheCmbGrupoPara()
        {
            var grupo = ClassGrupo.GetGrupoDescID();

            cmbGrupoPara.DataSource = grupo;
            foreach (var item in grupo)
            {
                cmbGrupoPara.DisplayMember = "Descricao";
                cmbGrupoPara.ValueMember = "ID";
            }
        }

        private void PreencheCmbGrupoSubDe()
        {
            var grupoSub = ClassGrupoSub.GetGrupoSubDescID(Convert.ToInt32(cmbGrupoDe.SelectedValue));


            cmbGrupoSubDe.DataSource = grupoSub;


            foreach (var item in grupoSub)
            {
                cmbGrupoSubDe.DisplayMember = "Descricao";
                cmbGrupoSubDe.ValueMember = "ID";
            }
        }

        private void PreencheCmbGrupoSubPara()
        {
            var grupoSub = ClassGrupoSub.GetGrupoSubDescID(Convert.ToInt32(cmbGrupoPara.SelectedValue));


            cmbGrupoSubPara.DataSource = grupoSub;


            foreach (var item in grupoSub)
            {
                cmbGrupoSubPara.DisplayMember = "Descricao";
                cmbGrupoSubPara.ValueMember = "ID";
            }
        }

        private void PreencheCmbGrupoSubFamiliaDe()
        {
            var grupoSubFamilia = ClassGrupoSubFamilia.getFamiliaDescID(Convert.ToInt32(cmbGrupoDe.SelectedValue),
                                                                        Convert.ToInt32(cmbGrupoSubDe.SelectedValue));

            cmbGrupoSubFamiliaDe.DataSource = grupoSubFamilia;
            foreach (var item in grupoSubFamilia)
            {
                cmbGrupoSubFamiliaDe.DisplayMember = "Descricao";
                cmbGrupoSubFamiliaDe.ValueMember = "ID";
            }
        }

        private void PreencheCmbGrupoSubFamiliaPara()
        {
            var grupoSubFamilia = ClassGrupoSubFamilia.getFamiliaDescID(Convert.ToInt32(cmbGrupoPara.SelectedValue),
                                                                        Convert.ToInt32(cmbGrupoSubPara.SelectedValue));

            cmbGrupoSubFamiliaPara.DataSource = grupoSubFamilia;
            foreach (var item in grupoSubFamilia)
            {
                cmbGrupoSubFamiliaPara.DisplayMember = "Descricao";
                cmbGrupoSubFamiliaPara.ValueMember = "ID";
            }
        }

        private void AtualizaGrdProdutoDe(int codGrupo, int codGrupoSub, int codGrupoSubFamilia)
        {
            ModelDB.Entities db = new ModelDB.Entities();
            var produto = (from p in db.Produto
                           where ((p.GrupoSubFamilia.codigoGrupo == codGrupo) &&
                                  (p.GrupoSubFamilia.codigoGrupoSub == codGrupoSub) &&
                                  (p.GrupoSubFamilia.codigoGrupoSubFamilia == codGrupoSubFamilia))
                           orderby p.codigo descending
                           select new
                           {
                               p.codigo,
                               p.descricao
                           });
            grdProdutoDe.DataSource = produto;
        }

        private void AtualizaGrdProdutoPara(int codGrupo, int codGrupoSub, int codGrupoSubFamilia)
        {
            ModelDB.Entities db = new ModelDB.Entities();
            var produto = (from p in db.Produto
                           where ((p.GrupoSubFamilia.codigoGrupo == codGrupo) &&
                                  (p.GrupoSubFamilia.codigoGrupoSub == codGrupoSub) &&
                                  (p.GrupoSubFamilia.codigoGrupoSubFamilia == codGrupoSubFamilia))
                           orderby p.codigo descending
                           select new
                           {
                               p.descricao,
                               p.GrupoSubFamilia.codigoGrupo,
                               p.GrupoSubFamilia.codigoGrupoSub,
                               p.GrupoSubFamilia.codigoGrupoSubFamilia,
                           });
            grdProdutoPara.DataSource = produto;
        }

        private void TransfereCodigos(int codGrupo, int codGrupoSub, int codGrupoSubFamilia,
                                      List<Int32> listaTransferir)
        {
            try
            {
               
                ModelDB.Entities db = new ModelDB.Entities();
               
                int i = 0;
                foreach (int a in listaTransferir)
                {
                    int cod = listaTransferir[i];

                    var transfProduto = (from p in db.Produto
                                         where (p.codigo == cod)
                                         select p).First();


                    IEnumerable<KeyValuePair<string, object>> entityKeyValues =
                    new KeyValuePair<string, object>[]
                    {
                        new KeyValuePair<string, object>("codigoGrupoSubFamilia", codGrupoSubFamilia),
                        new KeyValuePair<string, object>("codigoGrupoSub", codGrupoSub),
                        new KeyValuePair<string, object>("codigoGrupo", codGrupo)
                    };

                    transfProduto.GrupoSubFamiliaReference.EntityKey = new EntityKey(
                                                                                    "Entities.GrupoSubFamilia",
                                                                                    entityKeyValues);

                    transfProduto.UsuarioReference.EntityKey = new EntityKey("Entities.Usuario",
                                                                            "codigo",
                                                                            Business.Global.Usuario.GetCodigoUsuario());
                   
                    transfProduto.dataUltimaAtualizacaoCadastral = System.DateTime.Now;
                    //implementar usuario na  tabela

                    db.SaveChanges();
                    i++;
                    MessageBox.Show("Produtos Alterados com sucesso!");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Problema ao Atualizar\n"
                                + ex.Message,
                                "Atualizar Produto");
            }
        }

        private void cmbGrupoPara_EnabledChanged(object sender, EventArgs e)
        {
            PreencheCmbGrupoPara();
        }

        private void chkSeleciona_CheckedChanged(object sender, EventArgs e)
        {
            if (this.chkSeleciona.Checked)
            {
                foreach (DataGridViewRow row in this.grdProdutoDe.Rows)
                {
                    row.Cells["chkProdutoDe"].Value = true;
                }
            }
            else
            {
                foreach (DataGridViewRow row in this.grdProdutoDe.Rows)
                {
                    row.Cells["chkProdutoDe"].Value = false;
                }
            }
        }

        private void cmbGrupoDe_DropDownClosed(object sender, EventArgs e)
        {

            PreencheCmbGrupoSubDe();
            cmbGrupoSubDe.Enabled = true;
            if (cmbGrupoSubFamiliaDe.Enabled)
            {
                PreencheCmbGrupoSubFamiliaDe();
                AtualizaGrdProdutoDe(Convert.ToInt32(cmbGrupoDe.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubDe.SelectedValue),
                                Convert.ToInt32(cmbGrupoSubFamiliaDe.SelectedValue));
            }
        }
    }
}
Responder

Gostei + 0

09/11/2009

Fabio Mans

Mas não é muito diferente do que fazemos, se o Form tem muitos componentes e muitos eventos o que fazer? É isso mesmo.
Responder

Gostei + 0

09/11/2009

Daniel Vieira

Eu acho interessante a idéia de programar em camadas, principalmente com aquela idéia:
Mudo minha interface  e meu programa continua o mesmo (de WinForm pra Web)
Mudo meu banco e meu programa fica o mesmo (de SQL Server pra Oracle)

Nisso que eu queria chegar!
Mas do jeito que está meu programa acho que não dá pra aproveitar nada em outro projeto, está quase tudo dentro do form!

Qual a melhor maneira de se fazer um software em camadas?
Da pra fazer em um projeto que já está em desenvolvimento?
Se não, o que fazer? Continuar como está, reiniciar, abandonar, etc?


Essas dúvidas são cruéis, ainda mais pra mim que estou no primeiro projeto, e sou o único desenvolvedor até agora!
Responder

Gostei + 0

10/11/2009

Fabio Mans

Qual a melhor maneira de se fazer um software em camadas?   Eu utilizo como base o seguinte artigo, só não retorno um DataTable e sim um List<> http://www.dotnetfunda.com/articles/article18.aspx
Da pra fazer em um projeto que já está em desenvolvimento? Da sim, basta você ir mudando não sei como é seu tempo mas dá.
Se não, o que fazer? Continuar como está, reiniciar, abandonar, etc? Comece aplicando para as novas telas.   Fabio
Responder

Gostei + 0

10/11/2009

Daniel Vieira

Vou fazer esse projeto em casa, no meu C# Express.

Aqui no serviço vou continuar do jeito que está por enquanto.

Será que dá pra adaptar o projeto pra um windows frms?
Aqui o projeto é Windows Forms...
Responder

Gostei + 0

10/11/2009

Fabio Mans

Você diz Web Forms?   Da sim, a idéia é esta monta uma class Library e utiliza tanto na Web quanto no Windows.   Fabio   Será que dá pra adaptar o projeto pra um windows frms?
Aqui o projeto é Windows Forms...
Responder

Gostei + 0

25/11/2009

Devmedia

Daniel,
por falta de retorno estamos encerrando o seu chamado. Caso haja dúvidas sobre o assunto aqui tratado, basta postar a duvida aqui mesmo que o consultor voltará a lhe atender.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar