Jump to content

Archived

This topic is now archived and is closed to further replies.

Bruno Augusto

[Resolvido] E quando assinaturas de interface...

Recommended Posts

Estou lendo o tópico e acompanhando.. e boiando no raciocínio desses Observers.

Se não for pedir demais, poderiam me explicar qual a finalidade disso?

Share this post


Link to post
Share on other sites

De forma BEM abstrata e BEM a grosso modo seria fazer alguma coisa, assim que outra coisa acontecer mas sem ficar testando se essa coisa aconteceu ou não.

 

No Observer temos dois participantes: O Subject que é o assunto observável e N Observers, que são, como o nome já diz, os observadores.

 

Toda vez que um Subject fizer alguma coisa ele notifica, usualmente através do método de interface Subject::notify() à todos os Observadores anexados à ele que ele fez alguma coisa, não importa o quê.

 

Esse método faz é iterar por todos os Observers e invocar seus Observer::update(), passando à eles uma instância de si mesmo.

 

Por sua vez, cada Observer, em seus métodos Observer::update() executam alguma rotina, relacionada ou não ao Subject.

 

Nos primeiros posts tem um exemplo de um Subject de Gerenciador de Tabelas com um Observer de JavaScript Alert a ser disparado sempre que um registro for atualizado.

 

Desconsiderando o foco do problema quanto ao conflito de nomes, funcionaria mais ou menos assim:

 

<?php

class TableManager extends Subject {

   // ...

   public function update() {

       // Faz um UPDATE

       $this -> notify();
   }
}

<?php

class JavaScriptAlertObserver extends Observer {

   public function update( Subject $subject ) {

       echo '<script type="text/javascript">alert( \'Registro Atualizado\' );</script>";
   }
}

Share this post


Link to post
Share on other sites

Agora sim consegui entender. Mas não acha que isso dá volta demais, somente para ser um retorno de alguma ação? É que eu não vejo tanto sentido usar isto. Não se tem algma coisa a ver mas, eu prefiro fazer estes tipos de retornos via JSON, instancio minha classe e chame meu método passando-os como parametro no Ajax da jQuery.

Share this post


Link to post
Share on other sites

Esse foi um exemplo bem bobo, na grande maioria das vezes ele não é aplicado com esse propósito.

 

É que eu estava meio sem idéias... :P

Share this post


Link to post
Share on other sites
class ObserverWithData implements iObserverWithData {
       public function update(SubjectWithData $subject) {
               $data = $subject->getUpdateData(); // O problema está aqui...
               // Faz o que tem que fazer...
       }

}

 

Qual o problema aí??? ACOPLAMENTO!!!

 

Você está impondo que os objetos ObserverWithData conheçam os objetos SubjectWithData...

Tá, o problema aí pode ser minimizado se você declarar uma interface iSubjectWithData, mas ainda assim, muitas vezes não é o caso ótimo...

 

Um exemplo clássico em aplicações desktop para o padrão Observer é o chamado ActiveModel. A View observa o Model. Quando o Model é atualizado, ele dispara um notify que vai atualizar a View. Na web, isso seria possível com requisições push...

 

Entretanto, a View não conhece o model, ela apenas recebe dados dele. Nessa ideia, seria interessante que a assinatura do método update da View não recebece um subject (Model), e sim somente os dados prontos para serem exibidos.

 

O que estou querendo dizer com tudo isso é que a estrutura do Observer é variável demais pra você querer amarrar uma implementação em TODOS os objetos da sua aplicação...

Share this post


Link to post
Share on other sites

Isso eu entendi Henrique, tanto é que, como disse, já bolei uma implementação onde Subject e Observer como sendo interfaces, mas esse não é o ponto primordial do tópico.

 

Aliás, sua demonstração do "ser" e "pode ser" me elucidou diversos outros pontos. :grin:

 

O lcobucci me ajudou na questão de que os deveriam ser persistidos através de um método persist() ao invés do par insert() / update().

 

Para esse caso específico resolveu o problema de conflito de nomes.

 

Mas o que eu quero mesmo é aprender uma forma de quando ocorrer outro conflito, SE ocorrer tal conflito, eu possa resolver. Felizmente hoje não tenho mais conflitos, mas o futuro a Deus pertence, entende?

Share this post


Link to post
Share on other sites

É cara. Claro que existem pontos da OOP que eu preciso aprender e/ou melhorar, mas todo escopo do tópico é em torno de conflito de nomes e, consequentemente, de assinaturas.

Share this post


Link to post
Share on other sites

Bom, mas você não concorda que inicialmente o problema surgiu da aplicação de um padrão onde ele talvez não seja necessário? [sim, eu sou muito chato :P]

 

Mas enfim, quanto à questão dos nomes, não tem uma regra. Ainda mais no PHP, que não permite a definição de métodos com o mesmo nome, mas assinaturas diferentes como o C e o Java. A solução aqui é procurar sinônimos, ou refatorar o código de forma a não precisar daquele tal método...

 

Eu, por exemplo, não tenho métodos update e insert, tenho apenas um save, que faz as verificações necessárias para saber se atualiza ou insere...

 

Mas fora esse caso aí que você citou, de model observável, eu, de pronto, realmente não consigo pensar em nenhum outro caso de um conflito parecido.

 

Aí caímos naquele (seu e de várias pessoas, que já também foi meu) velho problema de querer contar com o ovo na cloaca (a outra palavra é proibida) da galinha e querer prever TODOS os problemas futuros possíveis. Desse jeito a coisa não flui. A não ser que sejam problemas estruturais, que podem te levar a um deadlock no futuro, você só precisa se preocupar com eles se realmente surgirem...

Share this post


Link to post
Share on other sites

Bom, mas você não concorda que inicialmente o problema surgiu da aplicação de um padrão onde ele talvez não seja necessário? [sim, eu sou muito chato :P]

Sim e não. Eu não tinha esse problema propriamente dito. Eu iria ter se seguisse adiante e antes de fazer poop, resolvi perguntar antes. :grin:

 

Mas enfim, quanto à questão dos nomes, não tem uma regra. Ainda mais no PHP, que não permite a definição de métodos com o mesmo nome, mas assinaturas diferentes como o C e o Java. A solução aqui é procurar sinônimos, ou refatorar o código de forma a não precisar daquele tal método...

Eu nem sabia que isso fosse possível em outras linguagens, mas como me parecia uma coisa imaginei que sim. :thumbsup:

 

Eu, por exemplo, não tenho métodos update e insert, tenho apenas um save, que faz as verificações necessárias para saber se atualiza ou insere...

Agora eu também terei, graças ao Icobucci ;)

 

Eu nunca entendi o motivo desse método existir nos códigos que via porque eu não entendia a aparente complexidade que suas implementações faziam. Eu pensava: Se vai inserir, insert(), se vai atualizar, update()

 

e quando via aquela verificação que delegava a responsabilidade para os métodos _insert() se não houvesse um ID e _update() se houvesse acabou por me confundir muito um pouco.

 

Mas fora esse caso aí que você citou, de model observável, eu, de pronto, realmente não consigo pensar em nenhum outro caso de um conflito parecido.

Nem eu. Porque acha que usei ele :lol:

 

Aí caímos naquele (seu e de várias pessoas, que já também foi meu) velho problema de querer contar com o ovo na cloaca (a outra palavra é proibida) da galinha e querer prever TODOS os problemas futuros possíveis. Desse jeito a coisa não flui. A não ser que sejam problemas estruturais, que podem te levar a um deadlock no futuro, você só precisa se preocupar com eles se realmente surgirem...

Mas eu não programo profissionalmente ainda.Posso me dar a esse luxo ^_^

Share this post


Link to post
Share on other sites

Ainda mais no PHP, que não permite a definição de métodos com o mesmo nome, mas assinaturas diferentes como o C e o Java.

 

Lembrando que PHP não possui essa funcionalidade, porque no caso seria desnecessário, visto que o mesmo não possui forte tipagem.

Share this post


Link to post
Share on other sites

Deus atendendo nossas preces, eu diria que apenas por enquanto.

 

Seria incrível se conseguissem combinar a tipagem fraca com forte na mesma linguagem, agradando gregos e troianos.

 

Imagina só o quão incrível seria poder retornar um tipo String ou Integer, quase como fazemos com um array.

 

Melhor ainda, podermos padronizar as assinaturas dos métodos que o excesso de legado bagunçou nas funções.

Share this post


Link to post
Share on other sites

Eu também acharia ótimo Bruno, isso foi proposto para os desenvolvedores, inclusive já com um patch com as funcionalidades, porém não foi aprovado.

Share this post


Link to post
Share on other sites

Eu também acharia ótimo Bruno, isso foi proposto para os desenvolvedores, inclusive já com um patch com as funcionalidades, porém não foi aprovado.

Se a idéia de tipagem forte no PHP seria ótimo, por que não foi aprovada? Poxa, realmente seria muito bom!

Share this post


Link to post
Share on other sites

Porque o PHP ganhou popularidade justamente pela tipagem fraca E sintaxe de fácil entendimento.

 

Por isso que só aceitariam o dia que algum gênio bolasse um modo de combinar ambas as tipagens na mesma linguagem. Daí o cara começa do jeito que está e quando tomar vergonha na cara quiser programar pra valer, começa a tipar as coisas.

Share this post


Link to post
Share on other sites

Não sei os motivos, o último request que eu tenho aqui no histórico é este: https://bugs.php.net/bug.php?id=43745

 

Se procurar talvez encontre mais. Na realidade estava planejado para ser implementado no PHP 5.4, já estava com os patchs no trunk do repositório, porém foram excluídos. :ermm:

 

Edit.

 

@Bruno, se não me engano, no patch que o sujeito disponibilizou, a tipagem era opcional, conforme a atual.

Share this post


Link to post
Share on other sites
Lembrando que PHP não possui essa funcionalidade, porque no caso seria desnecessário, visto que o mesmo não possui forte tipagem.

Aí depende... E pra criar métodos com números de parâmetros diferentes, mas com o mesmo nome???

Sem esse recurso, hoje funciona na gambiarra, com func_get_args e call_user_func_array.

Share this post


Link to post
Share on other sites

Eu evito ao máximo func_get_args(), tanto é que tenho só duas ocorrências dele em todas as classes.

 

Mas que é uma pena, é uma pena.

 

E esse (a) "helly" às vezes é um tremendo grosso (a). O cara criou o dele do zero, ao que parece melhor e mais completo que a SplTypes e ele (a) deu um baita esporro no cara.

 

Bem que ele podia disponibilizar. O duro seria ver os IDE's pintando metade do código de vermelho :yay:

 

Mas eu preferia MESMO uma abordagem OO. Poder fazer quase como no JavaScript:

 

$string = new String( 1 );

var_dump( $string ) // (string) '1' (length 1)

$string -> replace( '1', '2' );

var_dump( $string ) // (string) '2' (length 1)

Share this post


Link to post
Share on other sites

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.