ElasticSearch: Analyzer e seus amigos Tokenizer e Filter

Será que seria aceitável se o Google não ‘adivinha-se’, quando você está procurando por FLAMENGO, e você coloca em sua busca MENGO?
Se ele não te peguntar o que você quis dizer no erro de sua ortografia, seria chato, né?
😦
Se o motor de busca não “prever” o que estamos procurando, estaremos circunscritos a nos apaixonar por outro motor de busca que possa fazer essa tal “mágica”!
Um BING, quem sabe… 😛

Esse artigo focará na sutileza dos Analyzers, para tentar mostrar que ele são mais do que um valor exato de MENGO. Em suma, queremos ter uma melhor compreensão da pesquisa.

Com essa pequena introdução, poderei dar um enfoque melhor nos processos de análise do ElasticSearch.

Ao inserir dados em um índice no ElasticSearch, eles são armazenados em uma estrutura chamada de índice invertido, isso quer dizer que os dados são transformados e passam por um processo. Esse processo de transformação dos dados é chamados de análise.(ou Analysis).  

Curiosidade: Esse processo de analise tem dois pilares básicos:  tokenizing e normalizing.

O primeiro passo desse processo de analise é quebrar o texto em termos usando o Tokenizer após passar pelo filtro de caracteres, em seguida, esses termos são normalizados para serem facilmente pesquisáveis.

diagrama-textGeralmente um Analyzer é composto pode um tokenizing e um ou vários filters.

Curiosidade: O ElasticSearch faz o controle em tempos de execução da consulta, você está livre para usar um novo Analyzer a qualquer hora. 🙂

Voltando…

O ElasticSearch já vem com vários Analyzer instalados.

São eles:
Standard Analyzer
Utiliza o Standard Tokenizer para fatiar o texto, juntamente com o Standard Token Filter, Lowercase Token Filter e o Stop Token Filter. Normaliza símbolos, letras minusculas.

Simple Analyzer
Utiliza o Letter Tokenizer para fatiar texto, juntamente com o Lowercase Tokenizer.

Whitespace Analyzer
Utiliza o Whitespace Tokenizer para fatiar o texto com espaços.

Stop Analyzer
Utiliza o Letter Tokenizer para fatiar o texto, juntamente com o Lowercase Tokenizer e o Stop Token Filter. Remove palavras a partir de fluxos de token.

Pattern Anaylzer
Utiliza expressão regular para fatiar o texto.

Language Analyzer
Utiliza um conjuntos de Analyzers para analisar o texto para um determinado idioma.
São vários idiomas. =)

Os Analyzers seguem três ‘dogmas’ principais que utilizam filtros de caracteres, tokenizers e filtros de termos, são eles:

  1. Filtragem de caracteres
  2. Tokenização
  3. Filtragem de termos.

Pelo que já foi explicado acima, já podemos ter um entendimento de como funciona um Analyzer, certo?

Não?  😦

Ok, então segue mais uma explicação.

O Processo de analise se utiliza de um Tokenizer para quebrar um texto em tokens (ou termos). Antes dessa operação, o texto é transmitido através de algum filtro de caracteres.

Em seguida, os filtros de efetuam seu trabalho.

Esses filtros de caracteres são sempre utilizados antes do Tokenizer em um processo de analise.

O ElasticSearch foi construído com filtros personalizados e nos deixa construir nossos próprios filtros.

Já que falamos em Filtros, vamos ver alguns?

(Continua…)

Marcado com: , , ,
Publicado em Artigos

Shortest Paths (caminhos mínimos) Simples e direto…

Quando se fala de algoritmos de caminho mínimo o nome Edsger Dijkstra é sempre evidenciado.

Este algoritmo é capaz de determinar o caminho mínimo, partindo de um vértice de inicio para todos os outros vértices de um grafo.

O algoritmo leva o tempo O(m + n log n) caso seja usado um HEAP DE FIBONACCI , O(m log n)  caso seja usado um HEAP BINÁRIO e O(n²) caso seja usado um vetor para armazenar Q.

O Problema de caminhos mínimos se propõe em reduzir o excesso de travessias de um grafo entre dois vértices.

Essa redução é proposta pela soma dos pesos de cada aresta percorrida. Mediante a isso é dado um conjunto V de vértices e um, outro conjunto A de arestas  que por sua vez possui um peso entre  a ligação de dois  vértices.
Com essas informações é aplicado a fórmula:

f1
Onde dado qualquer valor de V será encontrado um caminho para P de, tal  que  f2é o menor caminho.

O caminho mínimo entre D e E não D-E, mas sim  D-F-E, com uma distância de 14.
f3

 

 

 

 

 

Usaremos o algoritmo de Dijkstra para descobrir o menor caminho entre duas estações de trem.

t1

 

 

 

 

 

 

 

 

 

 

Cada estação é um vértice e as ligações entre duas ou mais estações são nossas arestas com seus  respectivos pesos.

Quando Informamos uma origem e um destino  o programa nos dará o melhor/menor caminho do ponto A ao ponto B.

Em nosso exemplo o menor caminho entre a estação de  Manguinhos e Campo Grande  é a sinalizada em vermelho.

t2

 

 

 

 

 

 

 

 

 

 

 

 

Código fonte.

 

Modelos

public class Vertice
{
public string Id{get;set;}
public string Nome{get;set;}
public Point XY{get;set;}
public bool EhTerminal{get;set;}
public Vertice(string id, string nome, Point xy, bool ehTerminal = false)
{
Id = id;
Nome = nome;
XY = xy;
EhTerminal = ehTerminal;
}
}
public class Grafo
{
public List<Vertice> Vertices{get;set;}
public List<Aresta> Arestas{get;set;}
public Grafo(List<Vertice> vertices, List<Aresta> arestas)
{
Arestas = arestas;
Vertices = vertices;
}
}
public class Aresta
{
public string Id { get; set; }
public Vertice Origem { get; set; }
public Vertice Destino { get; set; }
  /// <summary>
        /// Calculo de distância entre Vértice A e Vértice B.
        /// </summary>
public int Peso
{
get
{
double x1 = Origem.XY.X, y1 = Origem.XY.Y;
double x2 = Destino.XY.X, y2 = Destino.XY.Y;
double peso = Math.Sqrt(Math.Pow(x2 – x1, 2.0) + Math.Pow(y2 – y1, 2.0));
return Convert.ToInt32(peso);
}
}
public Aresta(string id, Vertice origem, Vertice destino)
{
Id = id;
Origem = origem;
Destino = destino;
}
}

 

Algoritmo

public class Dijkstra
{
public List<Vertice> Vertices{get;set;}
public List<Aresta> Arestas{get;set;}
public HashSet<Vertice> VerticesVerificados{get;set;}
public HashSet<Vertice> VerticesNaoVerificados{get;set;}
public Dictionary<Vertice, Vertice> Predecessores{get;set;}
public Dictionary<Vertice, int> Distancia{get;set;}
public Dijkstra(Grafo grafo)
{
Vertices = new List<Vertice>(grafo.Vertices);
Arestas = new List<Aresta>(grafo.Arestas);
}
public void Executar(Vertice origem)
{
VerticesVerificados = new HashSet<Vertice>();
VerticesNaoVerificados = new HashSet<Vertice>();
Distancia = new Dictionary<Vertice, int>();
Predecessores = new Dictionary<Vertice, Vertice>();
Distancia.Add(origem, 0);
VerticesNaoVerificados.Add(origem);
while (VerticesNaoVerificados.Count() > 0)
{
Vertice vertice = MenorCaminho(VerticesNaoVerificados);
VerticesVerificados.Add(vertice);
VerticesNaoVerificados.Remove(vertice);
BuscarMenorDistancia(vertice);
}
}

private void BuscarMenorDistancia(Vertice vertice)
{
List<Vertice> VerticesAdjacentes = RetornarVizinhos(vertice);
foreach (Vertice adjacente in VerticesAdjacentes)
{
if (
RetornarMenorDistancia(adjacente) >
RetornarMenorDistancia(vertice) +
RetornarDistancia(vertice, adjacente))
{
if (Distancia.ContainsKey(adjacente))
Distancia[adjacente] = RetornarMenorDistancia(vertice) +
RetornarDistancia(vertice, adjacente);
else    Distancia.Add(adjacente, RetornarMenorDistancia(vertice) +
RetornarDistancia(vertice, adjacente));
if (Predecessores.ContainsKey(adjacente))
Predecessores[adjacente] = vertice;
else Predecessores.Add(adjacente, vertice);

VerticesNaoVerificados.Add(adjacente);
}
}
}

private int RetornarDistancia(Vertice vertice, Vertice adjacente)
{
foreach (Aresta aresta in Arestas)
{
if (aresta.Origem.Equals(vertice) &&
aresta.Destino.Equals(adjacente))
{
return aresta.Peso;
}
}
return int.MaxValue;
}

private List<Vertice> RetornarVizinhos(Vertice vertice)
{
List<Vertice> vizinhos = new List<Vertice>();
foreach (Aresta aresta in Arestas)
{
if (aresta.Origem.Equals(vertice) &&
!JahVerificado(aresta.Destino))
{
vizinhos.Add(aresta.Destino);
}
}
return vizinhos;
}

private bool JahVerificado(Vertice vertice)
{
return VerticesVerificados.Contains(vertice);
}

private Vertice MenorCaminho(HashSet<Vertice> vertices)
{
Vertice menorVertice = null;
foreach (Vertice vertice in vertices)
{
if (menorVertice == null)
menorVertice = vertice;
else if (RetornarMenorDistancia(vertice) < RetornarMenorDistancia(menorVertice))
menorVertice = vertice;
}
return menorVertice;
}

private int RetornarMenorDistancia(Vertice destino)
{
int distancia = Distancia.ContainsKey(destino) ? Distancia[destino] : -1;
if (distancia == -1)
return int.MaxValue;
return distancia;
}

public List<Vertice> RetornarCaminho(Vertice vertice)
{
List<Vertice> caminho = new List<Vertice>();
Vertice passo = vertice;
if (!Predecessores.ContainsKey(passo))
return null;
caminho.Add(passo);
while (Predecessores.ContainsKey(passo))
{
passo = Predecessores.ContainsKey(passo) ? Predecessores[passo] : null;
caminho.Add(passo);
}
caminho.Reverse();
return caminho;
}
}

Codigo fonte completo:  Algoritmo de Dijkstra

Fonte:

http://www.cs.auckland.ac.nz/software/AlgAnim/dijkstra.html

http://www.codeproject.com/Articles/24816/A-Fast-Priority-Queue-Implementation-of-the-Dijkst

http://www.codeproject.com/Articles/19919/Shortest-Path-Problem-Dijkstra-s-Algorithm

http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

 

Marcado com: , , , , ,
Publicado em Zoações...

Como usar os Delegados (delegates) e Eventos no C#

 

Tenho percebido que para muitas pessoas o uso de Delegados e Eventos não está muito claro.

Bom então vamos á uma breve explicação sobre este assunto.

Em C# os delegados são objetos de primeira classe, totalmente suportados pela linguagem, um delegado é um tipo de referência usado para encapsular um método como uma assinatura e um tipo de retorno específico. Você pode encapsular QUALQUER método usando um delegate, mas o método deve coincidir com o delegate usado.

Criamos um delegado com a palavra-chave delegate seguida de um tipo de retorno e a assinatura dos métodos que podem ser delegados a ela, conforme abaixo:

public delegate int delegateInteiro();

Está declaração define um delegado chamado delegateInteiro, que encapsulará quaisquer método que retorne um inteiro.

Uma vez definindo o delegado, você pode encapsular um método-membro com ele, instanciando-o e passando um método que coincida com o tipo de assinatura.

Acho que já deu para termos uma idéia de como um delegate funciona, agora vamos falar um pouco sobre os Eventos.

Os eventos em C# são introduzidos junto com os delegados. Por convenção, os manipuladores de eventos do .NET Framework retornam void e recebem dois parâmetros. O primeiro parâmetro é a ‘fonte’ do evento (ou seja, o objeto que faz a públicação). O segundo parâmetro é um objeto derivado do EventArgs. É recomendável que seus manipuladores de eventos sigam esse padrão.

O EventArgs é a classe que serve de base para todos os dados de evento. A assinatura de um evento é parecido com este abaixo:

public event delegateInteiro eventoInteiro;

Bom agora vamos criar um programa que simula uma passagem de tempo, Ao iniciar nosso exercício, adicione o namespace System.Threading, com ele iremos simular um intervalo de tempo e ver os dias passarem como se fosse em um passe de mágica.

A estrutura de nossa aplicação ficará assim:

Abaixo estamos criando nossa classe de eventos, para ser usado posteriormente em nossa aplicação.

public class MeuEventArgs : EventArgs

{

public readonly int _dia;

public readonly int _mes;

public readonly int _ano;

public MeuEventArgs(int dia, int mes, int ano)

{

this._dia = dia;

this._mes = mes;

this._ano = ano;

}

}

Iremos criar uma Estrutura com DIA MÊS E ANO.

struct structData {

public int dia;

public int mes;

public int ano;

}

Para podermos gerar nossa passagem de tempo, vamos implementar a classe que realmente fará isso.

public class PassagemDeTempo

{

// Note que estamos iniciando o mes com o valor 11 e o ano com o valor 1900.

private int _dia;

private int _mes = 11;

private int _ano = 1900;

private structData _data = new structData();

// Declaramos nosso delegado para encapsular os metodos.

public delegate void PassagemDeTempoHandler(object sender, MeuEventArgs e);

// Nosso evento, onde passaremos nosso delegado com seu método encapsulado.

public event PassagemDeTempoHandler OnPassagemDeTempo;

// Iniciando a passagem de tempo.

public void IniciarPassagem() {

for (;;)

{

// Aqui estamos dando um intervalo de ½ seg. para podermos ver essa passagem

Thread.Sleep(500);

// Gerando os dias,meses e anos e abastecendo nossa estrutura

_data.mes = gerarMes(_mes);

_data.dia = gerarDias(_dia);

_data.ano = gerarAno(_ano);

Sempre que passar um dia chamaremos nosso evento.

if (_data.dia != _dia)

{

MeuEventArgs eve = new MeuEventArgs(_data.dia, _data.mes, _data.ano);

if (OnPassagemDeTempo != null)

{

OnPassagemDeTempo(this, eve);

}

}

this._dia = _data.dia;

this._mes = _data.mes;

this._ano = _data.ano;

}

}

// os metodos abaixo são apenas tratamentos.

private int gerarDias(int dia){

if (dia >= 31) return 1;

return ++dia;

}

private int gerarMes(int mes){

if (_dia >= 31)

{

if (mes >= 12) return 1;

return ++mes;

}

else

return mes;

}

public int gerarAno(int ano) {

if (_mes == 12 && _dia == 31)

return ++ano;

else

return ano;

}

}

// Aqui em nossa classe MostrarPassagemDeTempo que exibimos os dias passando.

public class MostrarPassagemDeTempo

{

public void Subscribers(PassagemDeTempo _tempo)

{

//Arqui estamos encapsulando a funcao que mostra a passagem de tempo.

// note que estamos abastecendo um evento.

_tempo.OnPassagemDeTempo += new PassagemDeTempo.PassagemDeTempoHandler(Mostrar);

}

public void Mostrar(object sender,MeuEventArgs e)

{

Console.WriteLine(“{0}/{1}/{2}”, e._dia, e._mes, e._ano);

}

}

}

Para finalizar em nosso MAIN apenas escreveremos 4 linha de código:

PassagemDeTempo PassTmp = new PassagemDeTempo();

MostrarPassagemDeTempo MosPassTmp = new MostrarPassagemDeTempo();

MosPassTmp.Subscribers(PassTmp);

PassTmp.IniciarPassagem();

Ao executar está aplicação veremos o seguinte resultado.

 

 

 

Marcado com:
Publicado em Zoações...

Desculpa para aprender? [POST RÁPIDO]

Uma lista bem legal…

For C Tutorials.
http://www.codevdo.com/Languages/C
For C++ Tutorials.
http://www.codevdo.com/Languages/CPP
For C#.NET Tutorials.
http://www.codevdo.com/Languages/CSharp_Dotnet
For VB.NET Tutorials.
http://www.codevdo.com/Languages/VB_Dotnet
For Java Tutorials.
http://www.codevdo.com/Languages/Java
For Perl Tutorials.
http://www.codevdo.com/Languages/Perl
For MS Access Tutorials.
http://www.codevdo.com/Database/Ms_Access
For SQL Server Tutorials.
http://www.codevdo.com/Database/SQL_Server
For MySQL Tutorials.
http://www.codevdo.com/Database/MySQL
For Oracle Tutorials.
http://www.codevdo.com/Database/Oracle
For iPhone Apps Tutorials.
http://www.codevdo.com/Mobile/iPhone_Apps
For Android Apps Tutorials.
http://www.codevdo.com/Mobile/Android_Apps
For HTML/DHTML Tutorials.
http://www.codevdo.com/Web/HTML_DHTML
For jQuery Tutorials.
http://www.codevdo.com/Web/jQuery
For PHP Tutorials.
http://www.codevdo.com/Web/PHP

Marcado com: , , , , , , , , , , , , , , ,
Publicado em Zoações...

Boas práticas ao desenvolver em javascript

Hoje em dia javascript esta na moda, certo?

ERRADO!

O que esta na moda é o uso dos frameworks da vida.

Com isso, tenho notado que até mesmo alguns ‘plugins’ ou  até mesmo frameworks estão esquecendo de algo básico…

BOAS PRÁTICAS!

Essa foi minha motivação para fazer esse artigo, que foi  apresentado para a equipe de desenvolvimento de minha antiga empresa.

Então, vamos lá…

A primeira pergunta que faço em minha apresentação é

Onde começam as boas práticas?

Onde começam as boas práticas?

E sua resposta é óbvia…

Em você!

em você!

Nesse momento, muitas pessoas se fazem as seguintes perguntas:

  1. Como assim?
  2. Comigo? Blz, mas como gênio?

E a resposta para as perguntas supracitas é mais simples ainda…

Pensando antes de começar a fazer!!

Pensando antes de fazer!!!!

É algo simples e óbvio, mas acredite, com advento da tecnologia “CTRL+C , CTRL+V” e a febre dos plugins!
Muitos esquecem de ver se quele código ou plugin está fazendo o que você quer da forma correta, pois um axiôma que costumo usar é que “esta funcionando, não significa que esta certo.

Quando os plugins ou códigos não fazem o que precisamos, caimos no cenário de ter que codificar algo do zero, e acabamos caindo no uso abusivo dos frameworks…

Outro axiôma muito relevante que meu amigo Thiago Anselme sempre diz é “não existe bala de prata” ou seja, não existe uma solução,plugin,framework que resolverá todos os problemas de sua vida! 🙂

Criar algo do zero ou não. Usando boas práticas de programação e se possivel sem ficar dependente de framework…

  1. Para muitos… Isso da medo.
  2. Para muitos… Parece ser mais difícil… (até concordo…)
  3. Para muitos… Isso é impossível!

    ……………………………..
  4. Para poucos, blz tamo ae!  😉

Com isso vamos iniciar uma sequencia de códigos com o título “seria bom evitar”

Seria bom evitar!

Evitar o uso de eval ou Function

Function e a função a eval são operações pesadas que usados em excesso pode complicar a vida do interpretador.
Suas chamadas sãp convertidas em código fonte para código executável.

Lento:
function addPropriedade(objeto,propriedade,codigo){

objeto[propriedade] = new Function(codigo);

};
addPropriedade({},”nome”,”this.Variavel=2012″);

Rápido:
function addPropriedade(objeto,propriedade,funcao){

objeto[propriedade] = funcao;

};
addPropriedade({},”nome”,function(){ this.Variavel = 2012; });

Evitar passar,uma função na forma de strings, para setTimeout () e setInterval ()

Se você passar uma string em setTimeout() ou setInterval() a string será avaliada da mesma forma que o eval() que é lento.
Envolva seu código em uma função anônima. Assim o interpretado poderá  executar sua instrução de forma mais rápida durante a “compilação”.

Lento:

window.setInterval(“minhaFuncao()”,100);
window.setTimeout(“minhaFuncao()”,100);

Rápido:

window.setInterval(minhaFuncao,100);
window.setTimeout(minhaFuncao,100);

Sempre que puder, faça cache de valores variáveis

Lento:
O comprimento do arr array é recalculado a cada vez que o loop repete.

for(var i = 0; i < arr.length; i++){

//fazer algo…

}

Rápido:
Melhor maneira é para armazenar em cache o comprimento do array:

for(var i = 0,_length = arr.length; i < _length; i++){

//fazer algo…

}

Sempre que puder, faça cache de objetos DOM

Lento:

documento.getElementById(“elemento”).style.backgroundColor = “red”;
documento.getElementById(“elemento”).innerHTML = “….”;

Rápido:

var elemento = documento.getElementById(“elemento”);
elemento.style.backgroundColor = “red”;
elemento.innerHTML = “..”;

Evite pegar um formulário por getElementById

Em meus 6 anos de desenvolvimento de sistemas web, foi o que mais vi acontecer, algo muito recorrente.

As formas de de pegar o valor de um campo:

var form = document.forms[0];

#1
form[“buscar”].value

#2
form.buscar.value

#3
form.elements[“buscar”].value

Tantas formas e ainda vejo pessoas pegando o valor de um campo assim
$(“#buscar”).val() ou document.getElementById(“buscar”).value;

Remova referências que não serão mais usadas

..Lixo no lixo, blz? O browser agradece!

Não muito legal:
//inicio…
var elemento = document.getElementById(“elemento”);
//…
elemento.innerHTML = “valor… valor… “;
elemento.style.backgroundColor=”green”;
//…
//…
//…
//Fim…

Mais legal:
//inicio…
var elemento = document.getElementById(“elemento”);
var valor = “valor… valor…     “;
//…
elemento.innerHTML = valor;
elemento.style.backgroundColor=”green”;
//…
//…
//…
elemento = null;
delete valor;
//Fim…

Bom, fico por aqui..;

Existem vários outros exemplos de boas práticas, mas coloquei nesse artigo os que considero os mais gritantes…

Marcado com: , , , , , , , , ,
Publicado em Artigos

O que é REST ( Representational State Transfer ) ?

A grosso modo REST  é a evolução do SOAP, tá blz, já estou criando polêmica 🙂 , mas em minha simplória opinião é básicamente  “mais do mesmo”, SÓ que pensando em fazer algo realmente flexível.

Seu termo foi usado pela primeira vez na tese de doutorado do Dr. Roy Fielding em meiados de 2000, ele foi um dos criadores do nosso querido e tanto usado protocolo HTTP .

Pai do  protocolo HTTP ( esse é o pai da criança! ) =)

Pai do protocolo HTTP ( esse é o pai da criança! ) =)

Então…

Já esta claro que a web esta se tornando a cada dia mais voltada para serviços.  E tanto REST quando o bom e velho SOAP são ótimas  opções para integrações de sistemas através de redes privadas e públicas, sendo que o REST é mais focado em WEB 2.0, onde ser agil é de suma importância, e o SOAP para o segmento empresarial, onde é necessário um maior formalismo.

Acredito que em alguns anos o REST assumirá todos os segmentos de comunição HTTP, mas por enquanto…  =)

As aplicações que seguem os príncípios REST, são frequentemente chamados de RESTFull, que é muitas vezes confundido com uma especificação, já que suas chamadas são através dos verbos HTTP. Neste caso cada verbo tem uma responsábilidade.

Útilizações dos verbos HTTP:

  • GET : Representa uma acesso de buscar de algum recurso, leituras online ou em cache;
  • POST : Representado para efetuar ações de criação, sem o uso de cache;
  • PUT :  Representado como atualizações de um  recurso existente;
  • DELETE :  Como já está explicito, é representado para  deletar um recurso;

Comunicação não padronizada!

As trocas de informações entre clientes e serviços são definidos no cabeçalho (Content-Type) das requisições e respostas HTTP com isso formatos como JSON,RSS/ATom/XML ou formatos como JANE(Javascript Array Notation Expretion) e etc,  com isso a famosa interoperabilidade se faz presente em quaisquer tipo de tecnologia.

Quem já esta usando REST?

Segundo a wikipédia, empresas como Amazon,eBay e Yahoo já estão usando esta definição em suas aplicações.

Conclusão e  etc.

Esse tópico foi básicamente para explicar de forma rápida e prática o que é REST. 
O REST defende que não precisamos usar nenhuma ‘abstração’ para expor serviços web efetivos, precisamos apenas de um cliente, um serviço e informar como faze-lo (XML,JSON e etc), tudo em cima do protocolo HTTP,  ou seja…  Usar o que já temos para um propósito já existente  =)

Links que usei sobre REST

Next Stop

Passo a passo para criar um serviço REST com WCF

Marcado com: , , , , , , , , , ,
Publicado em Artigos

Design patterns – Factory (Fábrica)

Antes de começarmos, segue algumas pergunta/respostas:

  1. O que é padrão de projeto?
    R: http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software
  2. O que é Factory pattern (fábrica)?
    1. Explicação sobre o padrão Factory:R: http://en.wikipedia.org/wiki/Factory_method_pattern
      R: http://en.wikipedia.org/wiki/State_pattern
    2. Qual sua categoria?R: Criacional
    3. Sua estrutura padrão:Estrutura Básica

Bom, explicações dadas, agora vamos começar a brincar com nossopadrão. O exemplo usado foi de uma fábrica celular.

Com base na estrutura básica do padrão fábrica, criei as seguintes classes:

//Produto
    abstract class Celular
    {
protected string numero;
public Celular(string numero) { this.numero = numero; }
public abstract void Ligar(string numero);
   }

//Produto concreto.

class IPhone : Celular
{
public Hashtable Agenda = new Hashtable();
public IPhone(string numero) : base(numero) { }
public override void Ligar(string numero)
{
Console.WriteLine(“({0} ligando para {1}.”,this.numero,numero);
Agenda[numero] = ( Agenda[numero] == null)? 0 : Convert.ToInt32( Agenda[numero])+1;
}
}
class Nokia : Celular
{
public Nokia(string numero) : base(numero) { }
   public override void Ligar(string numero)
{
Console.WriteLine(“({0} ligando >>> {1}…”, this.numero, numero);
}
}

//Criador

abstract class Factory
{
private Celular celular;
public abstract void Criar( string numero);
public Celular Celular
{
get {   return celular;  }
set  { celular = value;  }
}
}

//Fábrica

class IPhoneFactory : Factory
{
public override void Criar(string numero)
{
this.Celular = new IPhone(numero);
}
}
class NokiaFactory : Factory
{
public override void Criar( string numero)
{
this.Celular = new Nokia(numero);
}
}

O Diagrama dessa implementação ficará assim:


Sua chamada ficará assim:

Marcado com: , , , , , ,
Publicado em Artigos