Jump to content

Archived

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

Rodolfo TI

Primeiro Projeto PHP Orientado a Objeto.

Recommended Posts

Acoplamento de uma classe com a ela mesma, por definição já é de 100%.

 

Aliás, nessa sua implementação ai, se eu for adicionar um SGBD novo na aplicação, vou ter que modificar a classe Conn. OCP foi pro espaço.

 

Não vou ficar discutindo isso aqui, acredite no que você achar melhor.

Share this post


Link to post
Share on other sites

Para a computação, acoplamento é o nível de inter-dependência entre os módulos de um software. O acoplamento está diretamente relacionado com a coesão, pois quanto maior for o acoplamento menor será o nível de coesão. Isto se deve ao fato de que, quando um módulo ou classe possui uma dependência muito forte por outro módulo ou classe, ele não é “forte” o suficiente para desepenhar suas tarefas de forma individual, dificultando, por exemplo, alterações no código da sua dependência (módulo ou classe de serviço).

 

Esse tipo de operação no código do Evandro Oliveira é 100% autocontida. NENHUM elemento exterior será utilizado para armazenar uma instância padrão do Printer, isso não gera acoplamento, pelo contrário, diminui.

 

O uso excessivo de static é ruim pois é de certa forma semelhante ao uso de variáveis globais em programação procedural.

A diferença é que nesse caso, você PRECISA de algo global. A diferença é que você pode não utilizar a propriedade estática se especificar isso passando parâmetros.

 

Se um dado objeto precisa sempre de um mesmo tipo de dependência e se é possível que a propriedade estática seja alterada no decorrer do código, basta lhe passar a dependência no construtor.

Share this post


Link to post
Share on other sites

você PRECISA de algo global

 

Como assim precisa? Não vejo nenhuma necessidade, esses recursos "defaultSomething" não são testáveis e possuem estado global.

 

 

 

Se um dado objeto precisa sempre de um mesmo tipo de dependência e se é possível que a propriedade estática seja alterada no decorrer do código, basta lhe passar a dependência no construtor.

 

Ficou confusa demais esta frase, mas para passar dependência ao construtor vc necessita de um objeto, com métodos estáticos vc não tem objeto.

 

<?php
Class::staticMethod();

 

 

Não há objeto.

Share this post


Link to post
Share on other sites

Como assim precisa? Não vejo nenhuma necessidade, esses recursos "defaultSomething" não são testáveis e possuem estado global.

Claro que é testável e o OBJETIVO é ter um estado global, mas tem que saber utilizar.

 

Exemplo: eu tenho uma implementação de um Table Data Gateway, que vai se conectar a um banco de dados através de um Adapter, o que me permitirá criar APIs uniformes para acessar qualquer banco de dados.

namespace Db;
class Table {
   // ... propriedades diversas
   /**
    * Armazena uma instância para um adapter que proverá uma interface com o banco de dados.
    */
   private $_adapter;

   public function __construct($name, AdapterInterface $adapter) {
       $this->_name = $name;
       $this->_adapter = $adapter;
   }
}

interface AdapterInterface {
   public function query($sql);
   public funciton fetchRow($opts...);
   public function fetchAll($opts...);
   public funciton insert($data);
   public funciton update($data, $cond);
   public funciton delete($cond);
}
E as implementações concretas:
namespace Db\Mysql;
class Adapter {
    //...
}

namespace Db\Pgsql;
class Adapter {
    //...
}
Agora toda vez que eu quiser instanciar um Db\Table eu tenho que fazer:

$table = new Db\Table("nome_da_tabela", new Db\Mysql\Adapter(array[configs...]));
$anotherTable = new Db\Table("outra_tabela", new Db\Pgsql\Adapter(array[configs...]));
Problemas aí?
  • A chatice de ter que sempre passar um adapter toda vez que criarmos um objeto Db_Table.
  • Se a senha do banco de dados mudar, por exemplo, terei que sair procurando onde alterar.
Solução #1: Singleton Registry

 

namespace Util;

class Registry {
    private __construct() {
        
    }

    public static getInstance() {
        // implementação padrão
    }
}

Aí eu vou lá e faço:

Util\Registry::getInstance()->set('default_adapter', new Db\Mysql\Adapter(array[configs...]));

// Em outra parte do código...

$table = new Db\Table(Registry::getInstance()->get('defaul_adapter'));

Problemas?

  • Ou eu crio uma dependência em todos os lugares para que conheçam Util\Registry ou pensando de outra forma, crio uma interface Registry e adiciono uma dependência a ela em TODOS os lugares do meu código, pois nessa filosofia eu vou precisar utilizar muito isso.
Exemplo:
namespace Application;
class SomeEntityModel {
private $_registry;
private $_mainTable;
public function __construct(Util\Registry\RegistryInterface $registry) {
$this->_registry = $registry;
$this->_mainTable = new Db\Table('some_entity', $this->_registry->get('default_adapter'));
}
// ... continua
}

Estou adicionando uma dependência desnecessária, só apra conseguir ter um adapter padrão.

 

Agora fazendo uso do static, eu modifico a classe Db\Table para isso:

namespace Db;
class Table {
   // ... propriedades diversas
   /**
    * Armazena uma instância para um adapter que proverá uma interface com o banco de dados.
    */
   private $_adapter;
   private static $_defaultAdapter;

   public function __construct($name, AdapterInterface $adapter == null) {
       $this->_name = $name;
       if($adapter !== null) {
           $this->_adapter = $adapter;
       } else {
           $this->_adapter = self::$_defaultAdapter;
       }

       if($this->_adapter === null) { 
           throw new Db\Exception('There are no adapters for this table work with.');
       }
   }

   // getters e setters para adapter e defaultAdapter
}

Agora eu posso fazer o seguinte:

// Em um arquivo de inicialização:
Db\Table::setDefaultAdapter(
    new Db\Mysql\Adapter([configs...]);
);

Agora, sempre que eu quiser realizar operações sobre esse banco de dados específico, eu não preciso especificar isso.

$table = new Db\Table("some_entity");

Mas SE EU PRECISAR GARANTIR que a operação seja feita sobre um banco de dados específico, basta eu lhe passar um adapter no construtor, que ele automaticamente sobrescreverá o estático:

$table = new Db\Table("some_entity", new Db\Pgsql\Adapter([configs...]);

Por que isso funciona?

Na maioria dos casos que eu já me deparei, você possui um banco de dados principal, o qual contém a maioria dos dados com os quais você irá trabalhar na sua aplicação.

 

Eventualmente, um conjunto menor de dados pode estar em outra base, até com um SGBD diferente. Sobre estes últimos, você força a sobrescritura do comportamento estático padrão fazendo como no último exemplo.

 

Além disso, se você altera a base de dados principal, muda a senha, muda o SGBD, sei lá, isso vai afetar todas as entidades, não? Justamente por isso há a instância estática defaultAdapter. Se eu altero isso, implicitamente altero todo o sistema. Entretanto, eu PRECISO fazer essa alteração global.

 

Só que aquele outro SGBD que eu utilizo não será afetado, pois todos os lugares que o utilizam tèm isso bem definido.

 

O acoplamento com quem realmente interessa, as classes de negócio, é baixo (não zero, pois isso é impossível). De fato, surge um acoplamento no arquivo de configuração, mas nesses você tem que mexer o tempo todo mesmo, então não importa.

 

No exemplo do Evandro, é a mesma coisa.

No contexto Java, por padrão, seu sistema fornece saídas na saída padrão do terminal. Só que você quer trocar isso, quer que todos os print() coloquem dados em um Socket.

 

Você teria que fazer isso todas as vezes?

objeto.print(new SocketOutputStream()); //inventei essa classe, só como exemplo
objeto.print(new SocketOutputStream()); 
objeto.print(new SocketOutputStream()); 
objeto.print(new SocketOutputStream()); 

Ou fazer:

objeto.setDefaultPrinter(new SocketOutputStream());

objeto.print();
objeto.print();
objeto.print();
objeto.print();

Enfim, TUDO tem uma utilidade, mas tem que saber usar.

Share this post


Link to post
Share on other sites

Alguns posts aqui merecem e muito uma área dedicada, ou até serem fixados como tutoriais.

 

Gente, depois que eu aprender isso , tenho que ficar muito féra, já li todos os posts repetidas vezes

 

já li :

 

Documentação PHP Interfaces

 

Criando Interfaces em PHP


Um exemplo da lógica de utilizar Interface com PHP

 

Utilizando interfaces em PHP

 

 

E consegui chegar somente nisso:

 

 

 

 
<?php
 //Seguindo o diagrama de classes defini essas interfaces, mas ta um pouco estranho
 interface Formacao{
 }
 //
 interface Instrutor{
  function ministrar();
 }
 interface Funcionarios{
  function confirmarPresenca();
 }
 interface Gerente{
  function cadastrarFormacao():
  function editarFormacao():
  function excluirFormacao():
  function cadastrarTurma():
  function editarTurma():
  function excluirTurma():
  function cadastrarInstrutor();
  function editarInstrutor();
  function excluirInstrutor();
 }
 interface  Turma {
 
 }
?>
 

 

 

Isso seguindo o diagrama abaixo:

 

classdiagramev5.jpg

 

 

 

Galera desculpe minha lentidão nas respostas, ando um pouco agarrado com trabalho, mas estou sempre que posso do uma relida, infelizmente sempre correndo

 

agradeço muito a ajuda de vocês!

 

@offtopic - Identação NEVER , kkkk to usando aqui no notepad sim, só que na hora do copiar não foi rs.

Share this post


Link to post
Share on other sites

Isso seguindo o diagrama abaixo:

 

classdiagramev5.jpg

Algum motivo em específico de ter voltado para esta versão do diagrama??

 

Ainda que não esteja ideal, julgo a mais recente melhor.

E quanto aos participantes ? Não seria turma -> participantes ?

 

classdiagramev4.jpg

Algumas considerações a fazer:

Algum funcionário cadastrado não poderá fazer nada? Se a resposta for uma negativa, não há um motivo claro para separar Participante de Funcionário.

 

Isso aqui continua me incomodando um bocado

a22bbe9d.png

 

Veja como fica a implementação

<?php

class Formacao
{
    private $codigo;
    private $ementa;
    private $nome;
}

Eu te pergunto: O que é possível fazer com esta classe??

Pra evitar confusões, sempre que for definir uma classe, pergunte-se "Qual problema ela resolve"?

Novamente, separe as definições de campos (atributos, propriedades) das definições de ações (métodos).

 

Para um programador, interessa a interface. O que tal tipo pode fazer. Para o banco, o que interessa são as informações que uma entidade carrega (estado).

 

http://forum.imasters.com.br/topic/487582-primeiro-projeto-php-orientado-a-objeto/page-3#entry1940732

Share this post


Link to post
Share on other sites

então vamos a parte complicada.

 

Instrutor é Funcionário assim como o gerente é.

 

Por que necessariamente 3 interfaces?

 

Sabemos que você pode fazer Classe extends interface1, interface2 mas como conciliar?

 

O gerente vai precisar confirmar uma pessoa? por que o gerente é funcionário então você precisaria implementar as 2 interfaces.

 

Seguindo esse racicinio eu acho que ficou meio redundante.

 

 

@offtopic

e que venha os profissionais quebrar minha perna.

Agora vem os cara chato fala que to errado ahuahuahuahuahaahuha #sad

Share this post


Link to post
Share on other sites

Instrutor é Funcionário assim como o gerente é.

 

Por que necessariamente 3 interfaces?

 

Sabemos que você pode fazer Classe extends interface1, interface2 mas como conciliar?

Herança também se aplica às interfaces

interface Gerente extends Funcionario
{...}

class ClasseGerente implements Gerente
{
    public function metodoDoFuncionario()
    {...}

    public function metodoDoGerente()
    {...}
}

Share this post


Link to post
Share on other sites

Bem, estado global não é testável (digo testes unitários, não rodar tudo com os var_dump da vida), e além disso viola o conceito de objetos, uma vez que você poderia alterar o estado de todos os objetos da classe sem ser no objeto em si, mas globalmente.

 

- http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/

- http://stackoverflow.com/a/8967424

 

---

 

 

 

class Formacao
{
    private $codigo;
    private $ementa;
    private $nome;
}

 

Uma boa prática é usar protected ao invés de private, private destrói a herança e normalmente viola o OCP.

 

---

 

Segregue as interfaces, não crie interfaces gordas, o participante que utilizará um derivado dessa cuja interface não necessita de saber todos os participantes, e um grande problema de interfaces gordas é quando você utiliza o "MethodNotImplementedException".

 

- http://en.wikipedia.org/wiki/Interface_segregation_principle

- http://stackoverflow.com/questions/58988/the-interface-segregation-principle

 

---

 

Sem querer ser um javeiro, mas sendo, lembre-se de alta coesão e baixo acoplamento.

Share this post


Link to post
Share on other sites

Uma boa prática é usar protected ao invés de private, private destrói a herança e normalmente viola o OCP.

a22bbe9d.png

 

Veja como fica a implementação[...]

Apenas realizei interpretação de UML. No diagrama postado originalmente, as definições são todas privadas. Como eu venho rebatendo durante todo o tópico: quem manda na implementação é o implementador
class User
{
    private $yaba_daba_dooh = false;

    public function login()
    {
        // Uma lógica muito complexa que calcula o
        // grau de rotação do meridiano de Greenwitch
        // em relação ao Sol e verifica se a última fase
        // da lua foi crescente...
        $this->yaba_daba_dooh = true;
    }

    public function isLoggedIn()
    {
        return $this->yaba_daba_dooh;
    }
}
Vai funcionar ou não vai??

 

Se a propriedade precisa/pode/deve ser modificada, algum acessor deve ser fornecido. Uma forma são métodos getters/setters, outra forma é diminuir a visibilidade. Cada uma foi criada com um propósito que ainda não vem ao caso.

 

Veja que o autor do tópico deseja descrever detalhadamente o domínio da aplicação, atribuir responsabilidades e denominar um fluxo de trabalho. Enquanto ainda engatinhamos com diagramas de classes, aqui já foi discutido uso ou não de estáticos e agora de visibilidade.

 

Eu poderia perfeitamente chegar com uma solução pronta e despejar a minha verdade. Não é este o meu objetivo. Quero caminhar no mesmo ritmo do @Rodolfo TI e, talvez, até mais devagar, dependendo se alguém esbarre em alguma dificuldade.

 

Primeiro, eu citei estáticos como uma alternativa a instâncias sem estado. Isso criou uma pilha onde se debatiam estáticos e chegamos até à (questionável) testabilidade de estáticos em ambientes unitários.

 

Agora vamos entrar em outro debate existencial sobre a real utilidade de visibilidade protegida, as vantagens, desvantagens e inflar ainda mais o tópico. Temos mais de 70 postagens onde - chutando por alto - umas 20 atendem ao propósito inicial.

 

Como já citei anteriormente, estou aberto a discussões e debates. Ver uma opinião externa ajuda a ampliar horizontes. Mas temos de utilizar a ferramenta corretamente. Abra um novo tópico para debater o uso de estáticos e mais um novo tópico para debater a visibilidade.

 

Quanto às respostas para dúvidas emergentes, o que agrega qualidade são as alternativas. Simplesmente apontar o dedo e dizer "Estáticos não são alternativa às classes sem estado porque não são testáveis" é vazio sem uma alternativa. Por favor complemente com algo do tipo "Prefira {sua alternativa aqui} pelos motivos X, Y e Z"

 

Entendo sua vontade de contribuir, admiro e respeito isso. Mas reforço que a ferramenta - fórum - está sendo utilizada de forma incorreta.

Share this post


Link to post
Share on other sites

Bem, orientação à objetos é teórica, acadêmica, logo não discutimos isto simplesmente só na prática, mas em teoria muito mais.

 

O problema é que pau que nasce torto não se endireita nunca. Mas prosseguir tópico ...

Share this post


Link to post
Share on other sites

Abrindo um parentese aí, para a parte de controller/view, tava pensando no uso do DTO.
Algo assim:

 

<?php
class UsuarioDTO
{
	public $nome;
	public $sobrenome;
}

class DTO
{
	public static function bind($dto)
	{
		$vars = get_class_vars(get_class($dto));
		print_r($vars);
		foreach($vars as $field => $value)
		{
			$dto->$field = $_REQUEST[$field];
		}
		
		return $dto;
	}
}

if($_SERVER['REQUEST_METHOD'] == 'POST')
{
	$UsuarioDTO = DTO::bind(new UsuarioDTO());
	
	print_r($UsuarioDTO);
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento sem título</title>
</head>

<body>
<form method="post" action="index.php">
	Nome: <input type="text" name="nome" />
    <br />
    Sobrenome:<input type="text" name="sobrenome" />
    <br />
    <input type="submit" value="Enviar" />
</form>
</body>
</html>

Share this post


Link to post
Share on other sites

Abrindo um parente aí, para a parte de controller/view, tava pensando no uso do DTO.

Algo assim:

 

class DTO

{

 

}

como assim uma classe vazia? explica melhor

Share this post


Link to post
Share on other sites

Bem, estado global não é testável (digo testes unitários, não rodar tudo com os var_dump da vida), e além disso viola o conceito de objetos, uma vez que você poderia alterar o estado de todos os objetos da classe sem ser no objeto em si, mas globalmente.

 

Não sei quem foi o infeliz que distorceu o "global é difícil de testar" para "global é IMPOSSÍVEL de testar". No caso que eu citei, vai do bom senso. A ideia é apenas ter uma inicialização de um adapter comum a maioria das instâncias de table. Se o programador quiser dar uma de Joselito e ficar trocando o adapter padrão no meio do código o problema é dele.

 

Muita gente diz:

- Nunca confie no programador.

 

Beleza, então eu amarro todas as posssibilidades por conta de alguns que não vão saber utilizar e prejudico os demais?

 

Se eu preciso agir globalmente em certos caso, por que vou fazer tudo de local em local até conseguir atingir o todo? Se eu posso afetar tudo de uma vez, vou fazer essa operação que é menos custosa e ponto final.

 

Uma boa prática é usar protected ao invés de private, private destrói a herança e normalmente viola o OCP.

 

Protected é uma PÉSSIMA prática e ela sim viola o OCP.

Open for extension, closed for modification.

Se eu dou livre acesso às minhas propriedades uma classe que pode fazer uma cagada qualquer, corro um sério risco. Aqui sim é perigoso confiar no programador, pois nem sempre ele terá seu código-fonte disponível para entender no que ele pode mexer ou não.

Via de regra: quer que uma variável privada seja acessível desde as classes filhas? Crie acessores protected.

 

Não seria DAO e VO?

Apesar de serem coisas diferentes, muitas vezes há uma confusão com VO e DTO, mas podem ser usados como sinônimos. Martin Fowler foi o cara que quis acabar com a confusão. VO são como strings em Java, objetos imutáveis, que tentam imitar tipos primitivos. Toda operação sobre um VO gera uma novo obejto. Atualmente a denominação mais correta para o padão citado é DTO, mas muita gente ainda o trata por VO.

Share this post


Link to post
Share on other sites

Meus amigos, li todas as postagens e tenho estudado muitos desses conceitos apresentados, em relação a esses conceitos surgiu uma dúvida: Para o primeiro projeto OO é viável usar conceitos tão complexos quanto alguns apresentados ? Ou deveria partir do simples, começar engatinhando ? Começar pelo começo, sim é pleonasmo , mas ainda sim é a melhor forma, no meu humilde ponto de vista é claro, de alguém que sabe muito pouco mas tem muita vontade de aprender.

 

Não quero que seja minha palavra a única verdade mas acho complicado alguém começar aplicando conceitos muito complexos.

 

Vamos começar de conceitos simples, como dependencia, visibilidade, etc.

 

Fiz alguns diagramas embora acredite que o problema esteja bem definido, para melhor compreensão minha e de quem ler o tópico a partir da ultima página ter uma base de onde queremos chegar:

 

Espero que não se encomodem com minha lentidão, muitos conceitos eu não conheço e paro sim para ler e muitas vezes reler, até chegar a conclusão se vai ser aplicado de acordo com o que tenho conhecimento ou se vai em confundir ainda mais.

 

Vamos aos diagramas.

 

O mais simples e inteligível, diagrama de atividades.

 

activitydiagram01.jpg

Junto a criação desses diagramas vi a necessidade de um novo objeto, o objeto turma. Caso não entendam favor me informar que detalho alguma parte.

 

Me questionei se Formação e Turma não seriam redundantes mas acredito que são objetos diferentes pois uma formação pode ser várias turmas e ainda sim serão a mesma formação, com o mesmo nome e carga horária.

 

Outro diagrama, Casos de Uso

 

usecasediagram01.jpg

 

 

Neste caso fiquei um pouco em dúvida na relação do aluno com a turma e suas ações :S.

 

Agora o mais temido, rsrs, brincadeiras a parte vamos a diagrama de classes.

 

classdiagramev6.jpg

Gerente, Aluno e Instrutor são todos funcionários porém com métodos diferentes para cada um deles .

 

Como declarar isso na interface ?

 

Ambos irão interagir de alguma forma com a turma.

 

Putz Rodolfo cadê a representação de herança no diagrama ? Sou ao escrever isso aqui e rever o diagrama me dei conta disso

 

Segue abaixo o diagrma já atualizado.

 

classdiagramev6.jpg

E agora vamos a definição das interfaces:

 

 

 
<?php
 //Seguindo o diagrama de classes defini essas interfaces, mas ta um pouco estranho
 
 interface Funcionarios{
  public $id;
  public $nome;
  public $mail;
  public $setor;
  public $nivelDeAcesso;
  extends  Gerente{
   private function cadastrarFormacao():
   private function editarFormacao():
   private function excluirFormacao():
   private function cadastrarTurma():
   private function editarTurma():
   private function excluirTurma():
   private function cadastrarInstrutor();
   private function editarInstrutor();
   private function excluirInstrutor();
   
   //são todas funções privadas porque somente subclasse gerente poderá utiliza-lá ? Correto ?
  }  
  extends Instrutor{
   private function ministrar();
  }
  extends Aluno{
   private function confirmarPresenca();
   
  }
 }
 interface Turma{
  public $id;
  public $formação;
  public $DataInicio;
  public $DataFim;
  public function ParticipaFormacao(); //fiquei na dúvida de como colocar os participantes aqui ;/
 }
 interface Formacao{
  public $id;
  public $nome;
  public $ementa;
  public $cargaHoraria; //Faltou no diagrama
 }
  
 
}
 
 
?>

 

 

A partir daqui vamos partir só para os códigos? Se for necessário farei mudanças no diagramas mas para uso pessoal, caso queiram eu posto a pedido mas vamos dar um gás nos códigos.

 

Evoluímos algo até aqui ?

 

Pessoal agradeço a ajuda de vocês!

Share this post


Link to post
Share on other sites

interfaces n tem atributos como $id, pq? lembre q interfaces e classes abstratas não podem ser instanciadas logo não tem estados.

Share this post


Link to post
Share on other sites

interfaces n tem atributos como $id, pq? lembre q interfaces e classes abstratas não podem ser instanciadas logo não tem estados.

 

Humm... então deveria declarar as classes normalmente e usar interfaces apenas para "chama-las" ?!

 

 
<?php
 //Seguindo o diagrama de classes defini essas interfaces, mas ta um pouco estranho
 public class funcionarios{
  public $id;
  public $nome;
  public $mail;
  public $setor;
  public $nivelDeAcesso;
 }
 interface Funcionarios{
  
  extends  Gerente{
   private function cadastrarFormacao():
   private function editarFormacao():
   private function excluirFormacao():
   private function cadastrarTurma():
   private function editarTurma():
   private function excluirTurma():
   private function cadastrarInstrutor();
   private function editarInstrutor();
   private function excluirInstrutor();
   
   //são todas funções privadas porque somente subclasse gerente poderá utiliza-lá ? Correto ?
  }  
  extends Instrutor{
   private function ministrar();
  }
  extends Aluno{
   private function confirmarPresenca();
  }
 }
 interface Turma{
  public function ParticipaFormacao(); //fiquei na dúvida de como colocar os participantes aqui ;/
 }
 interface Formacao{
 }
} 
?>

Share this post


Link to post
Share on other sites

 

 

Humm... então deveria declarar as classes normalmente e usar interfaces apenas para "chama-las" ?!

 

 

 
<?php
 //Seguindo o diagrama de classes defini essas interfaces, mas ta um pouco estranho
 public class funcionarios{
  public $id;
  public $nome;
  public $mail;
  public $setor;
  public $nivelDeAcesso;
 }
 interface Funcionarios{
  
  extends  Gerente{
   private function cadastrarFormacao():
   private function editarFormacao():
   private function excluirFormacao():
   private function cadastrarTurma():
   private function editarTurma():
   private function excluirTurma():
   private function cadastrarInstrutor();
   private function editarInstrutor();
   private function excluirInstrutor();
   
   //são todas funções privadas porque somente subclasse gerente poderá utiliza-lá ? Correto ?
  }  
  extends Instrutor{
   private function ministrar();
  }
  extends Aluno{
   private function confirmarPresenca();
  }
 }
 interface Turma{
  public function ParticipaFormacao(); //fiquei na dúvida de como colocar os participantes aqui ;/
 }
 interface Formacao{
 }
} 
?>

 

 

 

 

@Rodolfo TI, sugiro que dê uma lida no manual


interface MinhaInterface
{
    public function meuMetodoDeInterface();
    // Não há implementação
}

interface MinhaInterFaceComHeranca extends MinhaInterface
{
    public function meuOutroMetodo();
}

class MinhaClasse implements MinhaInterfaceComHeranca
{
    // Enquanto 'MinhaClasse' não definir uma implementação
    // de 'meuMetodoDeInterface' e 'meuOutroMetodo', haverá
    // O lançamento de um erro fatal
}

 

Para o primeiro projeto OO é viável usar conceitos tão complexos quanto alguns apresentados ?

Sim, deve fazer parte da sua cultura.

 

Ou deveria partir do simples, começar engatinhando?

Engatinhe absorvendo o máximo possível. Se houverem dúvidas, não hesite, pergunte. Repita, solicite expemplos e explicações alternativas até que não restem dúvidas.

 

 

O mais simples e inteligível, diagrama de atividades.

usecasediagram01.jpg

 

 

Apesar de ser um participante no domínio, não vejo Turma como um ator. Qual pergunta obterá uma resposta: "Quem é turma?" ou "O quê é uma turma?" ?

 

Quando a primeira pergunta tem uma resposta satisfatória, você tem um ator.

 

classdiagramev6.jpg

Algum funcionário cadastrado não poderá fazer nada? Se a resposta for uma negativa, não há um motivo claro para separar Participante de Funcionário.

 

Gerente, Aluno e Instrutor são todos funcionários porém com métodos diferentes para cada um deles .

 

 

 

 

Ambos, podem participar de uma formação, ou seja todos eles podem ser participantes de uma formação.

 

Gerente é um instrutor que, por sua vez, é um participante que, por sua vez é um funcionário. Cada um especializando um próximo nível, mas podendo utilizar todos os elementos do nível inferior. Você utiliza a entidade funcionário apenas para compartilhar os atributos.

 

Responda para si mesmo: "Um Gerente pode ministrar?".

 

classdiagramev6.jpg

 

Agora você abriu a visibilidade de Formação, mas continua sem responder à pergunta: "O que eu posso fazer com uma Formação??

 

A situação piorou um pouco. Do jeito que está, eu posso substituir a classe Formação por um Array mantendo a mesma funcionalidade. Tanto Formação quanto Array apenas armazenam valores.

 

Remodele Formação até que você consiga responder à pergunta "O que eu posso fazer com uma Formação?".

 

Novamente, separe este diagrama em interface/entidades. Pra um programador, interessa a interface. Pra um DBA, interessam os atributos.

 

http://forum.imasters.com.br/topic/487582-primeiro-projeto-php-orientado-a-objeto/page-3#entry1940732

 

 




 
<?php
 //Seguindo o diagrama de classes defini essas interfaces, mas ta um pouco estranho
 
 interface Funcionarios{
  public $id;
  public $nome;
  public $mail;
  public $setor;
  public $nivelDeAcesso;
  extends  Gerente{
   private function cadastrarFormacao():
   private function editarFormacao():
   private function excluirFormacao():
   private function cadastrarTurma():
   private function editarTurma():
   private function excluirTurma():
   private function cadastrarInstrutor();
   private function editarInstrutor();
   private function excluirInstrutor();
   
   //são todas funções privadas porque somente subclasse gerente poderá utiliza-lá ? Correto ?
  }  
  extends Instrutor{
   private function ministrar();
  }
  extends Aluno{
   private function confirmarPresenca();
   
  }
 }
 interface Turma{
  public $id;
  public $formação;
  public $DataInicio;
  public $DataFim;
  public function ParticipaFormacao(); //fiquei na dúvida de como colocar os participantes aqui ;/
 }
 interface Formacao{
  public $id;
  public $nome;
  public $ementa;
  public $cargaHoraria; //Faltou no diagrama
 }
  
 
}
 
 
?>

 

 

Como já foi dito, em PHP não há implementação na interface.

 

interfaces n tem atributos como $id, pq? lembre q interfaces e classes abstratas não podem ser instanciadas logo não tem estados.

A partir daqui vamos partir só para os códigos?

A partir do diagrama de classes/entidades desmembra-se o desenvolvimento entre a programação e modelagem do DB.

Evoluímos algo até aqui ?

Você quem vai dizer:

 

classdiagram1d.jpg

 

 

1diagram.png

 

Veja que, independente de como se chamem os atributos, desde que a implementação siga as interfaces propostas, você pode ficar responsável por implementar uma classe, eu pego outra, o @shini outra e, quando juntarmos tudo, tudo deve funcionar corretamente

 

 

 

Participante.php


<?php

namespace Vendor\Interface

interface Participante
{
    /**
     * @param \string $nome
     * @param \string $email
     * @param \string $setor
     */
    public function __construct($nome, $email, $setor);

    /**
     * @return \string|\null
     */
    public function obterNome();

    /**
     * @param \string $nome
     * @return \string|\null
     */
    public function definirNome($nome);

    /**
     * @return \string|\null
     */
    public function obterEmail();

    /**
     * @param \string $email
     * @return \string|\null
     */
    public function definirEmail($email);

    /**
     * @return \string|\null
     */
    public function obterSetor();

    /**
     * @param \string $setor
     * @return \string|\null
     */
    public function definirSetor($setor);

    /**
     * @param Turma $turma
     * @return \boolean
     */
    public function confirmarParticipacao(Turma $turma);

    /**
     * @param Turma $turma
     * @return \boolean
     */
    public function cancelarParticipacao(Turma $turma);

    /**
     * @return \Traversable
     */
    public function obterInscricoes();

    /**
     * @return \Traversable
     */
    public function obterInscricoesCanceladas();

    /**
     * @return \Traversable
     */
    public function obterInscricoesConfirmadas();
}

Instrutor.php


<?php

namespace Vendor\Interfaces;

interface Instrutor extends Participante
{
    /**
     * @param Turma $turma
     * @return \boolean
     */
    public function ministrar(Turma $turma);
}

 

Gerente.php


<?php

namespace Vendor\Interfaces;

interface Gerente extends Instrutor
{
    /**
     * @param Instrutor $instrutor
     * @return \boolean
     */
    public function definirInstrutor(Instrutor $instrutor);

    /**
     * @param Formacao $formacao
     * @return \boolean
     */
    public function definirFormacao(Formacao $formacao);

    /**
     * @param Participante $participante
     * @return \boolean
     */
    public function definirParticipante(Participante $participante);

    /**
     * @param Turma $turma
     * @return \boolean
     */
    public function definirTurma(Turma $turma);

    /**
     * @param Formacao $formacao
     * @return \boolean
     */
    public function excluirFormacao(Formacao $formacao);

    /**
     * @param Instrutor $instrutor
     * @return \boolean
     */
    public function excluirInstrutor(Instrutor $instrutor);

    /**
     * @param Turma $turma
     * @return \boolean
     */
    public function excluirTurma(Turma $turma);

    /**
     * @param Instrutor $instrutor
     * @param Turma $turma
     * @return \boolean
     */
    public function designarInstrutor(Instrutor $instrutor, Turma $turma);

    /**
     * @param Participante $participante
     * @param Turma $turma
     * @return \boolean
     */
    public function inscrever(Participante $participante, Turma $turma);
}

 

Formacao.php


<?php

namespace Vendor\Interfaces;


interface Formacao
{
    /**
     * @param \string $nome
     * @param \string $ementa
     * @param Instrutor $instrutor @optional
     */
    public function __construct($nome, $ementa, Instrutor $instrutor = null);

    /**
     * @return \string
     */
    public function obterNome();

    /**
     * @param \string $nome
     * @return \boolean
     */
    public function definirNome($nome);

    /**
     * @return \string
     */
    public function obterEmenta();

    /**
     * @param \string $ementa
     * @return \boolean
     */
    public function definirEmenta($ementa);

    /**
     * @return Instrutor
     */
    public function obterInstrutor();

    /**
     * @param Instrutor $instrutor
     * @return Instrutor|\null
     */
    public function definirInstrutor(Instrutor $instrutor);
}

 

 

 

Share this post


Link to post
Share on other sites

×

Important Information

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