quinta-feira, 24 de abril de 2008

Aulas 19 e 20 - Projeto Orientado a Objetos

Padrão Singleton

O padrão Singleton assegura que apenas uma única instância daquela classe vai existir. Por exemplo, seu sistema pode ter apenas um gerenciador de janelas, ou gerenciador de impressão, ou então um único ponto de acesso ao banco de dados. A maneira mais fácil de fazer uma classe que possua uma única instância dela mesma é utilizar uma variável estática na classe, onde será guardada a referência para a instância corrente. No caso do Singleton, a classe deve ter um construtor private, ou seja, ela não poderá ser instanciada diretamente, mas sim fornecer um método comum para que a instância única da classe seja retornada. Cada vez que esse método for chamado, ele deve checar se já existe uma instância da classe e retorná-la, caso contrário ele deve instanciar a classe, guardar a referência ao objeto no atributo estático da classe e então retorná-lo

public class Singleton {

private static Singleton instance;

private Singleton() { }
public static Singleton getInstance() {

if (instance == null) instance = new Singleton();
return instance;
}
}

O código acima pode ser problemático em ambientes multi-threads, ou seja, ele não é uma solução thread-safe. Se uma thread chamar o método getInstance() e for interrompida antes de realizar a instanciação, uma outra thread poderá chamar o método e realizar a instanciação. Neste caso, duas instâncias serão construídas, o que fere os requisitos do singleton.

Utilizando atributo Synchronized

Uma solução para este problema seria utilizar o atributo synchronized em getInstance(), como visto no código abaixo, para que uma outra thread não possa acessá-lo até que a thread que o acessou pela primeira vez tenha terminado de executar.

public class Singleton {
private static Singleton instance; private Singleton() { }
public static synchronized Singleton getInstance()
{ if (instance == null) instance = new Singleton();
return instance;
}
}

Problemas com Synchronized

O problema com o synchronized é que a sincronização é bastante custosa. Estima-se que métodos sincronizados sejam cerca de cem vezes mais lentos que métodos não sincronizados.Uma alternativa simples, rápida e thread-safe é a instanciação do singleton assim que ele for declarado.

public class Singleton {

private static Singleton instance = new Singleton(); private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}


Bibliografia

Marcoratti - O padrão Singleton <http://www.macoratti.net/net_psgt.htm> Acessado em 23 Abr 2008, 13:31;

Universia - Padrões de Projeto <http://www.universia.com.br/mit/6/6.170/pdf/6.170_lecture-12.pdf> Acessado em 23 Abr 2008, 13:25;

Wikipedia Singleton <http://pt.wikipedia.org/wiki/Singleton> Acessadp e 23 Abr 2008, 13:55;

quinta-feira, 17 de abril de 2008

Aulas 17 e 18 - Projeto Orientado a Objetos

Padrões GOF


Padrão GOF contém 23 padrões e algumas formas de classificação são elas: criação, estrutura e comportamento, sendo que a criação está relacionando na criação propriamente dita na criação do objeto, a estrutura nos mostra as associações entre as classes e objetos e o comportamento divide as responsabilidades entre as classes ou objetos.
Os padrões GOF está voltado também na qualidade de um software usando o conceito de herança, polimorfismo, modularidade, composição e abstração, a alta coesão e o baixo acoplamento é um fator importante nos padrões GOF para satisfazer a qualidade do software.
Metsker classifica os padrões GOF como:


· Interface – é o meio que liga uma classe ou objeto através de um adaptador;


· Responsabilidade – atribui responsabilidade as classes e objetos, também utilizados nos padrões GRASP;


· Construção – e a construção propriamente dita de uma classe, por exemplo: fabricam instâncias Building;


· Operação – parte de métodos das classes;


· Extensão – Extensibilidade, polimorfismo.


Padrão Interface – Adapter


Adapter, também conhecido como Wrapper, é um padrão de projeto de software ou de desenho (do inglês design pattern). Este padrão é utilizado para 'adaptar' a interface de uma classe. O Adapter permite que classes com interfaces incompatíveis possam interagir.
Adapter permite que um objeto cliente utilize serviços de outros objetos com interfaces diferentes por meio de uma interface única


Podemos ter a seguinte situação:


















O Cliente precisa comunicar-se com o Adaptado, mas possuem interfaces incompatíveis. Então, ele comunica-se com o Adapter, fazendo a este uma solicitação. O Adapter repassa a solicitação para o Adaptado. O Adaptado precisa então devolver uma resposta para o Cliente, mas novamente não é possível devido à incompatibilidade de interfaces. A solução é enviar a resposta para o Adapter que irá em seguida encaminhá-la para o Cliente, completando assim o ciclo de comunicação. O adapter é encarregado de fazer o meio entre as classes que não se comunicam dando uma flexibilidade as classes que não são compatíveis umas com as outras.



Em seguida podemos observar um código que representa o padrão Adapter:


//Classe Cliente


public class cliente extends Adaptador{

public static void main(String[] args) {


cliente c = new cliente(); c.executa();


}

}




//Classe Adaptador



public class Adaptador {

public void executa(){


Resultado a = new Resultado();

a.metodo();
}


}




//Classe Resultado


public class Resultado {


public void metodo(){


System.out.println("Resultado da Oeracao")

}


}


Nesse caso foi utilizado as classes Cliente, Adaptador e Resultado, para representadar o padrão Adapter.




Bibliografia

Christopher Alexander. A Pattern Language. Estados Unidos da América: Oxford University Press, 1977. ISBN 0195019199

JEEBrasil Padrão de projeto Adapter <http://www.jeebrasil.com.br/mostrar/38> Acessado em 16 de Abr de 2008.

Wikipedia Adapter <http://pt.wikipedia.org/wiki/Adapter> Acessado em 16 de Abr de 2008.

sexta-feira, 28 de março de 2008

Aulas 15 e 16 - Projeto Orientado a Objetos

Alta Coesão

Alta coesão indica qual o grau de relacionamento entre os módulos de uma classe, sintonia que há entre eles, o grande problema de se ter uma alta coesão é o gerenciamento da complexidade, deve-se manter esse tipo de coesão, faz com que elimina ligações, reduz métodos sem ligações entre eles, um trabalha sinergia do outro.

Baixa Coesão podemos citar vários problemas encontrados:

Difícil de entender – muitos métodos numa mesma classe;
Difícil de reusar- muitas classes diferentes para gerenciar;
Difícil de manter – dificuldade no entendimento das classes;
Assumir responsabilidade demais – há uma sobrecarga de classes com muitas responsabilidades;
Solução para os problemas relacionados acima:
Cada classe com sua própria responsabilidade, por exemplo, um módulo de venda não tem a responsabilidade de conectar com o Banco não é missão dela.
Temos alguns tipos de coesão:
- Coincidental
- Lógica
- Temporal
- Procedural
- De comunicação
- Sequencial
- Funcional

Conseqüências de Alta Coesão

1 – Melhora o reuso
2 – Sistemas mais fáceis de manter
3 – Melhora o Entendimento
4 – Melhora a granularidade e conseqüentemente aumenta o reuso
Padrão Controlador
Se preocupa com eventos da classe cadidata para tratar isso, normalmente para cada caso de uso tem que ter um controlador, um controlador apenas recebe o evento e passa adiante, delega para alguém.

quinta-feira, 20 de março de 2008

Aulas 13 e 14 - Projetos Orientado a Objetos

Acoplamento de Controle

Utiliza flags de controle entre os objetos de forma que um controle o outro, para percebemos um acoplamento de controle basta observar quais são as classes que estão acopladas e verificar a característica básica do controle que é justamente a passagem de parâmetros que controla outra classes, no exemplo mostrado em aula, observamos que há uma classe Lâmpada e uma classe Circuito, nesse caso a classe Circuito controla a classe Lâmpada, passando flags de ajuste para executar alguma ação (Ligar, Desligar, Piscar), há também na classe Lâmpada o problema de ajuste do código o código proposto em primeiro momento funciona, mas poderá ser refatorado criando apenas métodos que serão executados a partir de outra classe(Circuito) , em segundo momento decompomos a classe em múltipla operações primitivas, onde criamos um método para cada ação.

Duas soluções para o Acoplamento de Controle:

1º - Decompor a classe em métodos para se tornar mais transparente;
2º - Utilizar tratamento de exceções.

Acoplamento de Dados Globais

Quando dois ou mais objetos compartilham os mesmos dados, todas as classes trabalham com as mesmas coisas, o problema desse acoplamento é que fica escondido, tornando mais difícil perceber o problema.


Acoplamento de Dados Internos


Quando um objeto altera os dados locais de outro, por exemplo, dados protected e public no caso da linguagem Java, para que esse problema se torne mais difícil de acontecer utiliza-se private e métodos assessores e mutatórios para evitar o acoplamento de dados internos, essas duas soluções lembra o encapsulamento de dados.

quinta-feira, 13 de março de 2008

Aulas 11 e 12 - Projetos Orientado a Objetos

Acoplamento

Pode-se dizer que acoplamento e à medida que dá a dependência de uma classe com outra, é possível identificar um acoplamento quando uma classe está relacionada com outra através de uma associação, agregação, etc, está ramificada em:

- Conhecimento
- Dependência
- Interligação

O que estudamos nas aulas 10 e 11 como utilizar o baixo acoplamento que é uma boa prática de projeto, quanto menor o relacionamento entre as classes melhor é a manutenção, a portabilidade e a reutilização da mesma. O problema de um alto acoplamento, torna difícil o entendimento, a reutilização e a mudança se necessário de um lugar para outro, a solução mais óbvia é aplicar o Baixo Acoplamento.

Podemos citar alguns tipos de Acoplamento:

Acoplamento de dados 1 (-)
Acoplamento de controle 2
Acoplamento de dados Globais 3
Acoplamento de dados Internos 4 (+)

quinta-feira, 6 de março de 2008

Aulas 9 e 10 - Projeto Orientado a Objetos

Padrões GRASP

- Criador

Nas duas aulas ministradas discutimos o funcionamento do Padrão criador, exemplificando com códigos.

Produto

Public calss produto {

private Integer idProduto;
private String Descricao;
private Double valorUnitario;

public String GetDescricao() {

return descrição;
}

Public void setDescricao (String descricao) {

This.descricao = descircao;
}
}

ItemVenda

Public calss produto {

private Double qtde;
private Produto p;

public void setP(Produto p) {


this.p = p;
}
}

Venda

public class Venda {

private set itemVendaList = new HashSet();
private Data dataVenda;
private Integer idVenda;

public criarItemVenda (Produto P, Dpuble qtde) {

ItemVenda i = new ItemVenda();
i.setP(P);
i.setQtde(qtde);
itemVendaList.add(i);

}

}

No trecho de código está sendo aplicado não só o padrão criador, mas também o especialista, é importante citar também que há um encapsulamento do objeto.

quinta-feira, 28 de fevereiro de 2008

Aulas 7 e 8 - Projetos Orientado a Objetos

Padrões GRASP

· Criador

O padrão guia a atribuição de responsabilidades relacionadas com a criação de objetos.

Padrão criador segue 5 condições básicas para atribuir responsabilidades:

Atribua à classe B a responsabilidade de criar uma nova instância da classe A se uma das seguintes condições for verdadeira:

- B agrega objetos de A
- B contém objetos de A
- B registra instâncias de objetos de A
- B usa objetos de A
- B tem os valores iniciais que serão passados para
objetos de A, quando de sua criação

Objetos agregados, contêineres e registradores são bons candidatos à responsabilidade de criaroutros objetos, algumas vezes o criador é o objeto que conhece os dados iniciais do objeto a ser criado, o ideal é manter o Baixo Acoplamento e a Alta Coesão.