POO - dilema do ovo e da galinha

Delphi

20/09/2006

tenho uma classe de configuração que possui parametros para acessar um servidor de FTP, por exemplo, com host, logi, senha, diretorio etc...
e uma outra classe que serve pra fazer downloads e uploads de arquivos via ftp. Ela usa uma instancia da classe anterior para saber a configuração que deve usar para acessar o servidor e transferir os arquivos.

caso as propriedades da classe de configuração esteja em branco, ela seta as propriedades com valores default, acessa o ftp, baixa um arquivo e le esse arquivo configurando suas propriedades com o que tirar de dentro dele, ou seja, nesse arquivo tem login, senha, host etc.

para não repetir o codigo de download de ftp dentro da classe de configuração eu uso ...... A CLASSE DE TRANSFERENCIA.... e a classe de transferencia, para configurar seus ftp´s internos, USA A CLASSE DE CONFIGURAÇÃO...

pra resumir, tenho 2 classes que são assim:

TConfiguracao
....
public
property Host: string;
property Login: string;
property Senha: string;
property Transf: TTransferencia;
function BaixaArquivoConf;
end;

TTransferencia
public
property Conf: TConfiguracao;
procedure EnviaFTP;
procedure MandaEmail;
end;

function TConfiguracao.BaixaArquivoConf;
begin
transf.baixaarquivo;
configura;
end;



Obviamente que as classes fazem muito mais que isso, coloquei isso so pra ilustrar, ms por exemplo: a classe de configuração tem todas as configurações do meu software, parametros de aceso ao bd, versao etc, e eu uso ela em todos os programas menores relacionados ao meu programa principal, e a classe de transferencia, alem de se configurar sozinha, ela manda ftp, e-mail etc...

é um dilema de ovo e galinha, eu não sou muito bom em POO e este é um dos meus softwares que eu estou tentando melhorar. Eu sei que é muito feio uma classe usar a outra e vice-versa ao mesmo tempo, então o que eu faço?

Grato!


Vitor Rubio

Vitor Rubio

Curtidas 0

Respostas

_rodfaria_

_rodfaria_

20/09/2006

Antes de declarar TConfiguracao você pode indicar que TTransferencia existe e é uma classe.
TTransferencia = class;

TConfiguracao
...

TTransferencia
...


Mas sou contra. Quando duas classes se usam, é necessário fatorar o código e criar uma terceira classe que será usada pelas duas primeiras.
Uma classe não pode ter muitas responsabilidades. Ou ela armazena dados ou exibe dados ou faz conexões ou registra coisas em log etc.


Referência:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20884171.html


GOSTEI 0
Vitor Rubio

Vitor Rubio

20/09/2006

O esquema de declarar a classe antes
TTransferencia = class; 

eu já conhecia, e chama-se declaração prévia. O que eu não consegui fazer mesmo é fatorar a minha classe em duas outras, o pulo do gato que é difícil....

Mas eu fiz assim: como a glasse de enviar arquivos só usa a classe de configuração para configurar seus ftp´s e smtp´s, então uma das propriedades da classe de envio é um objeto da classe de configuração.

agora como a classe de configuração só usa a classe de envio uma única vez, que é na atualização, eu fiz o seguinte: no proprio metodo de atualização eu crio uma instancia da classe de envio, uso e edestruo. Eu tambeem posso passar esse método de atualização para a aclasse de envio ou para uma outra classe equalquer, assim ela não usaria mais a classe de envio.

Valew!


GOSTEI 0
Cesar Romero

Cesar Romero

20/09/2006

uma parte do design deste projeto (inicial) que não me deixa a vontade é o fato da classe de transferencia conhecer a classe de configuração, imagine o seguinte cenário:

Suas classes fazem parte de uma biblioteca que será utilizada por terceiros, então se o ´terceiro´ que só precisa de usar a transferência de arquivos se tocar que ele pode explorar todas as informações declaradas na classe de configuração será fácil ele saber mais detalhes de outras partes do sistema, como senhas de conexão com banco, tudo isto só uma hipótese pra você pensar se deve ou não continuar com o design desta forma.

Minha sugestão é ter 3 classes:
1) A primeira ter todas as configuracoes
2) Uma para quer crie os serviços, neste caso o Serviço de transferência de arquivos
3) A classe de transferência de arquivos, com o construtor Create modificado, para receber os parâmetros necessários Host, Login, Passwd, etc...

Acho que neste caso a classe intermediária seria uma implementação do padrão [i:cf7c63618f]Mediator[/i:cf7c63618f] já que esta classe estaria encapsulando a comunicação entre as classes configuração e transferência de arquivos.

Um texto sobre Mediator se interessar também.
http://www.dofactory.com/Patterns/PatternMediator.aspx

Não sei como você esta programando, eu utilizo muito Interfaces e acho que num caso como este ficaria muito boa a implementação.
Se quiser continuar discutindo sobre isto, e uma implementação com interfaces, diga como posso ajudar.

[]s[/i]


GOSTEI 0
Vitor Rubio

Vitor Rubio

20/09/2006

A classe não vai ser usada por terceiros, e todos os programadores envolvidos no projeto tem conhecimento das senhas. As senhas são criptografadas de qualquer forma.

Eu acho que entendi o que você quis dizer, veja se está certo, supondo que vamos trabalhar apenas com FTP e que a classe de transferencia de arquivos usa um idFTP internamente (podia ser qualquer coisa)

//esta classe é desconhecida do terceiro (caso houvesse)
TClasseConfiguracao = class
...
property login...
property host...
property senha..
end;

//esta classe e desconhecida do terceiro (caso houvesse)
TClasseTransferencia 
...
property FTP: TIdFtp; //esse é criado no oncreate dessa classe
end;


TClasseMediadora
...
private
procedure Configura(conf: TclasseConfiguracao; transf: TclasseTransferencia)
public
procedure envia;
procedure recebe;
end;


procedure TClasseMediadora.envia;
var
Conf: TclasseConfiguracao;
transf: TclasseTransferencia;
begin
conf := TclasseConfiguracao.create;
transf := TclasseTransferencia.create;
configura(conf, transf);
transf.ftp.put(<parametros do put>);
transf.free;
conf.free;
end;



É mais ou menos assim que se deve fazer, ou a classe mediadora deve ter como propriedades, ou parametros do create, objetos do tipo configuracao e transferencia? Onde entrariam as interfaces nesse caso?


Obrigado pela força!


GOSTEI 0
Cesar Romero

Cesar Romero

20/09/2006

É assim mesmo,
Interfaces mudaria completamente a forma de desenvolver, se der tempo vou montar um exemplo e posto aqui.

[]s


GOSTEI 0
POSTAR