terça-feira, abril 21, 2009

Singleton

Dar a responsabilidade a uma classe de controlar a própria instância, e fornecer um método de acesso a mesma de forma global. Utilize o padrão quando for necessário apenas uma instância em toda aplicação.

1. Diagrama de Classes


2. Benefícios x Desvantagens

Controle da instância: possui total controle da instância, já que a mesma controla o processo de instancialização.

3. Código

C#


using System;
using System.Collections.Generic;
using System.Text;

namespace SingletonTest
{
class Program
{
static void Main(string[] args)
{
ServerList serverList = ServerList.GetInstance();
}
}

///
/// Singleton
///

sealed class ServerList
{
private static readonly ServerList _instance = new ServerList();
private IDictionary _serverList = new Dictionary();

private ServerList()
{
PopulateServerList();
}

///
/// Popula lista para o exemplo.
///

private void PopulateServerList()
{
this._serverList.Add("DarthVader", "192.168.0.1");
this._serverList.Add("Luke Skywalker", "192.168.0.2");
this._serverList.Add("Obi-wan", "192.168.0.3");
}

///
/// Retorna a instancia de ServerList.
///

public static ServerList GetInstance()
{
return _instance;
}
}
}




VB.NET


Imports System
Imports System.Collections.Generic
Imports System.Text

Namespace SingletonTest
    Class Program
        Private Shared Sub Main(ByVal args As String())
            Dim serverList__1 As ServerList = ServerList.GetInstance()
        End Sub
    End Class
   
    '''
    ''' Singleton
    '''

    NotInheritable Class ServerList
        Private Shared ReadOnly _instance As New ServerList()
        Private _serverList As IDictionary(Of String, String) = New Dictionary(Of String, String)()
       
        Private Sub New()
            PopulateServerList()
        End Sub
       
        '''
        ''' Popula lista para o exemplo.
        '''

        Private Sub PopulateServerList()
            Me._serverList.Add("DarthVader", "192.168.0.1")
            Me._serverList.Add("Luke Skywalker", "192.168.0.2")
            Me._serverList.Add("Obi-wan", "192.168.0.3")
        End Sub
       
        '''
        ''' Retorna a instancia de ServerList.
        '''

        Public Shared Function GetInstance() As ServerList
            Return _instance
        End Function
    End Class
End Namespace


Prototype

Especifica os tipos de objetos a serem criados usando uma instância-protótipo e cria novos objetos a partir do mesmo. É recomendado usar este padrão para evitar o crescimento de classes no sistema.

O Prototype e os padrões fábricas são similares em sua intenção. Ambos são criacionais. A principal diferença entre eles é o modo que são construídos. Nas fábricas, pode-se construir objetos usando os parâmetros de cada vez. Há uma similaridade entre eles. O Prototype, é usado para clonar qualquer objeto dado.

1. Diagrama de Classes


2. Considerações Importantes

Provavelmente, o mais complexo deste padrão é o método clone. Ela pode ser difícil quando a clone faz o uso de referências. Para algumas linguagens mais dinâmicas, como nosso c# ou Java, há uma implementação genérica por reflection. O nome da técnica usada é shallow clone. Naturalmente, você pode implementar seu próprio método-clone, programaticamente (chama-se deep copy).

3. Benefícios x Desvantagens

Acrescenta e remove produtos em tempo de execução: permite que incorporar uma nova classe concreta apenas registrando uma instância prototype com o cliente, deixando flexível instalar e remover em tempo de execução.

Reduz o número de subclasses: evita uma explosão de classes, pois permite clonar em vez de criar um novo objeto. Você pode especificar novos objetos a partir da variação da estrutura interna.

4. Código


C#

using System;
using System.Collections.Generic;
using System.Text;

namespace Prototype
{
class Program
{

static void Main(string[] args)
{
Prototype p1 = new ConcretePrototype1("ID");
Prototype c1 = p1.Clone();
Console.WriteLine("Real: {0} - Clone: {1}", p1.ToString(), c1.ToString());
}
}


public abstract class Prototype
{

private string _id;


public string ID
{
get { return _id; }
set { _id = value; }
}


public Prototype(string id)
{
this.ID = id;
}


public override string ToString()
{
return ID;
}

public abstract Prototype Clone();
}



public class ConcretePrototype1 : Prototype
{

public ConcretePrototype1(string id) :base(id)
{
}



public override Prototype Clone()
{
return (Prototype)this.MemberwiseClone();
}
}


public class ConcretePrototype2 : Prototype
{
public ConcretePrototype2(string id) : base(id)
{
}

public override Prototype Clone()
{
return (Prototype)this.MemberwiseClone();
}
}
}




VB.NET

Imports System
Imports System.Collections.Generic
Imports System.Text

Namespace Prototype
    Class Program
       
        Private Shared Sub Main(ByVal args As String())
            Dim p1 As Prototype = New ConcretePrototype1("ID")
            Dim c1 As Prototype = p1.Clone()
            Console.WriteLine("Real: {0} - Clone: {1}", p1.ToString(), c1.ToString())
        End Sub
    End Class
   
   
    Public MustInherit Class Prototype
       
        Private _id As String
       
       
        Public Property ID() As String
            Get
                Return _id
            End Get
            Set(ByVal value As String)
                _id = value
            End Set
        End Property
       
       
        Public Sub New(ByVal id As String)
            Me.ID = id
        End Sub
       
       
        Public Overloads Overrides Function ToString() As String
            Return ID
        End Function
       
        Public MustOverride Function Clone() As Prototype
    End Class
   
   
   
    Public Class ConcretePrototype1
        Inherits Prototype
       
        Public Sub New(ByVal id As String)
            MyBase.New(id)
        End Sub
       
       
       
        Public Overloads Overrides Function Clone() As Prototype
            Return DirectCast(Me.MemberwiseClone(), Prototype)
        End Function
    End Class
   
   
    Public Class ConcretePrototype2
        Inherits Prototype
        Public Sub New(ByVal id As String)
            MyBase.New(id)
        End Sub
       
        Public Overloads Overrides Function Clone() As Prototype
            Return DirectCast(Me.MemberwiseClone(), Prototype)
        End Function
    End Class
End Namespace

Builder

Separa a construção de um objeto complexo de sua representação para que o processo de construção seja criado diferentemente da suas representações.

1. Diagrama de Classes

2. Participantes

Builder: especifica a interface abstrata para criação de partes de um objeto-builder.
BuilderConcreto: constrói as partes do produto, define e mantém a representação que cria.
Diretor: constrói um objeto apartir da interface do builder.
Produto: representa o objeto complexo que será construído.

3. Vantagens e Desvantagens

Permite variar a representação interna de um produto. O objeto builder fornece ao produtor/diretor apenas a sua abstração. Ou seja, o mesmo tem apenas a assinatura dos métodos para controlar a produção.

O cliente não precisa saber como é o processo interno do método. Apenas é de responsabilidade dele delegar aos métodos da abstração.

4. Padrões com a mesma finalidade

A diferença do padrão Builder para o Abstract Factory é o domínio da fabricação do objeto, pois cria o objeto final passo-a-passo.

5. Código


C#


using System;
using System.Collections.Generic;
using System.Text;

namespace BuilderTest
{
class Program
{
static void Main(string[] args)
{
Director director = new Director();

Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();

director.Construct(b1);
BuilderTest.ConcreteBuilder2.Product p1 = b1.GetResult();

p1.Show();
Console.ReadKey();
}
}

class Director
{
public void Construct(Builder builder)
{
builder.BuildPartA();
builder.BuildPartB();
}
}
abstract class Builder
{
public abstract void BuildPartA();
public abstract void BuildPartB();
public abstract BuilderTest.ConcreteBuilder2.Product GetResult();
}

class ConcreteBuilder1 : Builder
{
private BuilderTest.ConcreteBuilder2.Product _product = new BuilderTest.ConcreteBuilder2.Product();

public override void BuildPartA()
{
_product.Add("PartA");
}

public override void BuildPartB()
{
_product.Add("PartB");
}

public override BuilderTest.ConcreteBuilder2.Product GetResult()
{
return _product;
}
}

class ConcreteBuilder2 : Builder
{
private Product _product = new Product();

public override void BuildPartA()
{
_product.Add("PartX");
}

public override void BuildPartB()
{
_product.Add("PartY");
}

public override Product GetResult()
{
return _product;
}


public class Product
{
private IList _parts = new List();

public void Add(string part)
{
_parts.Add(part);
}

public void Show()
{
Console.WriteLine("\n Product Parts");

foreach (string part in _parts)
{
Console.WriteLine(part);
}

}
}
}
}



VB.NET


Imports System
Imports System.Collections.Generic
Imports System.Text

Namespace BuilderTest
    Class Program
        Private Shared Sub Main(ByVal args As String())
            Dim director As New Director()
           
            Dim b1 As Builder = New ConcreteBuilder1()
            Dim b2 As Builder = New ConcreteBuilder2()
           
            director.Construct(b1)
            Dim p1 As BuilderTest.ConcreteBuilder2.Product = b1.GetResult()
           
            p1.Show()
            Console.ReadKey()
        End Sub
    End Class
   
    Class Director
        Public Sub Construct(ByVal builder As Builder)
            builder.BuildPartA()
            builder.BuildPartB()
        End Sub
    End Class
    MustInherit Class Builder
        Public MustOverride Sub BuildPartA()
        Public MustOverride Sub BuildPartB()
        Public MustOverride Function GetResult() As BuilderTest.ConcreteBuilder2.Product
    End Class
   
    Class ConcreteBuilder1
        Inherits Builder
        Private _product As New BuilderTest.ConcreteBuilder2.Product()
       
        Public Overloads Overrides Sub BuildPartA()
            _product.Add("PartA")
        End Sub
       
        Public Overloads Overrides Sub BuildPartB()
            _product.Add("PartB")
        End Sub
       
        Public Overloads Overrides Function GetResult() As BuilderTest.ConcreteBuilder2.Product
            Return _product
        End Function
    End Class
   
    Class ConcreteBuilder2
        Inherits Builder
        Private _product As New Product()
       
        Public Overloads Overrides Sub BuildPartA()
            _product.Add("PartX")
        End Sub
       
        Public Overloads Overrides Sub BuildPartB()
            _product.Add("PartY")
        End Sub
       
        Public Overloads Overrides Function GetResult() As Product
            Return _product
        End Function
       
       
        Public Class Product
            Private _parts As IList(Of String) = New List(Of String)()
           
            Public Sub Add(ByVal part As String)
                _parts.Add(part)
            End Sub
           
            Public Sub Show()
                Console.WriteLine(vbLf & " Product Parts")
               
                For Each part As String In _parts
                    Console.WriteLine(part)
                   
                Next
            End Sub
        End Class
    End Class
End Namespace

Abstract Factory

A intenção do padrão é criar um objeto-fábrica que orquestra a instância dos objetos que serão produzidos, fornecendo uma interface comum para estes objetos.

1. Diagrama de Classes

2. Desvantagens x Benefícios

• Por isolar as classes concretas, o cliente controla o componente apenas a partir da assinatura da abstração da classe.
• Facilidade na troca de família de objetos, uma vez que a família implementa a mesma abstração e a fábrica é montada apenas na instancialização do objeto.
• Dificuldade em extensão da família. Estender uma classe pode acarretar dificuldades, pois deve se alterar a assinatura da fábrica e todas as classes herdadas.
• Há um senso harmônico entre os objetos produzidos. Todos possuem a mesma característica de sua abstração. E ainda há a possibilidade de fabricação de objetos apenas uma vez de cada vez.

3. Código


C#


using System;
using System.Collections.Generic;
using System.Text;

namespace AbstractFactoryTest
{
class Program
{
static void Main(string[] args)
{

// Cria celulares da Companhia A.
CellphoneFactory factoryOne = new CompanyACellphoneFactory();
Industry industryOne = new Industry(factoryOne);
industryOne.Produce();

// Cria celulares da Companhia B.
CellphoneFactory factoryTwo = new CompanyBCellphoneFactory();

Industry industryTwo = new Industry(factoryTwo);
industryTwo.Produce();

Console.ReadKey();

}
}

#region ProductsFromACompany


public class CompanyATouchedScreenCellphone : AbstractCellphoneWithTouchedScreen
{
public override string ToString()
{
return "Um celular touch screen da empresa A";
}
}

public class CompanyARegularCellphone : AbstractRegularCellphone
{
public override string ToString()
{
return "Um celular comum da empresa A";
}
}

#endregion


#region ProductsFromBCompany


public class CompanyBTouchedScreenCellphone : AbstractCellphoneWithTouchedScreen
{

public override string ToString()
{

return "Cellphone touch screen da empresa B";

}
}


public class CompanyBRegularCellphone : AbstractRegularCellphone
{
public override string ToString()
{
return "Um celular comum da empresa B";
}
}

#endregion

#region Abstracoes dos Produtos


public abstract class AbstractCellphoneWithTouchedScreen
{
public abstract override string ToString();
}


public abstract class AbstractRegularCellphone
{
public abstract override string ToString();
}

#endregion


abstract class CellphoneFactory
{
public abstract AbstractCellphoneWithTouchedScreen CreateCellphoneA();
public abstract AbstractRegularCellphone CreateCellphoneB();
}

class CompanyACellphoneFactory : CellphoneFactory
{

public override AbstractCellphoneWithTouchedScreen CreateCellphoneA()
{
return new CompanyATouchedScreenCellphone();
}


public override AbstractRegularCellphone CreateCellphoneB()
{
return new CompanyARegularCellphone();
}
}


class CompanyBCellphoneFactory : CellphoneFactory
{
public override AbstractCellphoneWithTouchedScreen CreateCellphoneA()
{
return new CompanyBTouchedScreenCellphone();
}



public override AbstractRegularCellphone CreateCellphoneB()
{
return new CompanyBRegularCellphone();
}
}

class Industry
{
private AbstractCellphoneWithTouchedScreen cellphoneOne;
private AbstractRegularCellphone cellphoneTwo;


public Industry(CellphoneFactory cellphoneFactory)
{
this.cellphoneOne =cellphoneFactory.CreateCellphoneA();
this.cellphoneTwo = cellphoneFactory.CreateCellphoneB();
}

public void Produce()
{
Console.WriteLine("Construção do celular: {0}. ", this.cellphoneOne.ToString());
Console.WriteLine("Construção do celular: {0}. ", this.cellphoneTwo.ToString());

}
}
}




VB.NET


Imports System
Imports System.Collections.Generic
Imports System.Text

Namespace AbstractFactoryTest
    Class Program
        Private Shared Sub Main(ByVal args As String())
           
            ' Cria celulares da Companhia A.
            Dim factoryOne As CellphoneFactory = New CompanyACellphoneFactory()
            Dim industryOne As New Industry(factoryOne)
            industryOne.Produce()
           
            ' Cria celulares da Companhia B.
            Dim factoryTwo As CellphoneFactory = New CompanyBCellphoneFactory()
           
            Dim industryTwo As New Industry(factoryTwo)
            industryTwo.Produce()
           
               
            Console.ReadKey()
        End Sub
    End Class
   
    #Region "ProductsFromACompany"
   
   
    Public Class CompanyATouchedScreenCellphone
        Inherits AbstractCellphoneWithTouchedScreen
        Public Overloads Overrides Function ToString() As String
            Return "Um celular touch screen da empresa A"
        End Function
    End Class
   
    Public Class CompanyARegularCellphone
        Inherits AbstractRegularCellphone
        Public Overloads Overrides Function ToString() As String
            Return "Um celular comum da empresa A"
        End Function
    End Class
   
    #End Region
   
   
    #Region "ProductsFromBCompany"
   
   
    Public Class CompanyBTouchedScreenCellphone
        Inherits AbstractCellphoneWithTouchedScreen
       
        Public Overloads Overrides Function ToString() As String
           
               
            Return "Cellphone touch screen da empresa B"
        End Function
    End Class
   
   
    Public Class CompanyBRegularCellphone
        Inherits AbstractRegularCellphone
        Public Overloads Overrides Function ToString() As String
            Return "Um celular comum da empresa B"
        End Function
    End Class
   
    #End Region
   
    #Region "Abstracoes dos Produtos"
   
   
    Public MustInherit Class AbstractCellphoneWithTouchedScreen
        Public MustOverride Overloads Overrides Function ToString() As String
    End Class
   
   
    Public MustInherit Class AbstractRegularCellphone
        Public MustOverride Overloads Overrides Function ToString() As String
    End Class
   
    #End Region
   
   
    MustInherit Class CellphoneFactory
        Public MustOverride Function CreateCellphoneA() As AbstractCellphoneWithTouchedScreen
        Public MustOverride Function CreateCellphoneB() As AbstractRegularCellphone
    End Class
   
    Class CompanyACellphoneFactory
        Inherits CellphoneFactory
       
        Public Overloads Overrides Function CreateCellphoneA() As AbstractCellphoneWithTouchedScreen
            Return New CompanyATouchedScreenCellphone()
        End Function
       
       
        Public Overloads Overrides Function CreateCellphoneB() As AbstractRegularCellphone
            Return New CompanyARegularCellphone()
        End Function
    End Class
   
   
    Class CompanyBCellphoneFactory
        Inherits CellphoneFactory
        Public Overloads Overrides Function CreateCellphoneA() As AbstractCellphoneWithTouchedScreen
            Return New CompanyBTouchedScreenCellphone()
        End Function
       
       
       
        Public Overloads Overrides Function CreateCellphoneB() As AbstractRegularCellphone
            Return New CompanyBRegularCellphone()
        End Function
    End Class
   
    Class Industry
        Private cellphoneOne As AbstractCellphoneWithTouchedScreen
        Private cellphoneTwo As AbstractRegularCellphone
       
       
        Public Sub New(ByVal cellphoneFactory As CellphoneFactory)
            Me.cellphoneOne = cellphoneFactory.CreateCellphoneA()
            Me.cellphoneTwo = cellphoneFactory.CreateCellphoneB()
        End Sub
       
        Public Sub Produce()
            Console.WriteLine("Construção do celular: {0}. ", Me.cellphoneOne.ToString())
               
            Console.WriteLine("Construção do celular: {0}. ", Me.cellphoneTwo.ToString())
        End Sub
    End Class
End Namespace


Introdução aos Padrões de Criação

Os padrões de criação são os padrões de projeto que abstraem o processo de instanciação das classes, ajudando o sistema ser independe dos objetos concretos criados.

Para o sistema, tudo o que se sabe é que suas classes são definidas por classes abstratas. Isso facilita muito expansão do sistema no futuro. Iremos analisar os cinco padrões de criação escritos pela gangue dos quatro (GoF).




Abstract Factory criar um objeto-fábrica que orquestra a instância dos objetos que serão produzidos.
BuilderSepara a construção de um objeto complexo de sua representação.
PrototypeEspecifica os tipos de objetos a serem criados usando uma instância-protótipo e cria novos objetos a partir do mesmo.
SingletonDar a responsabilidade a uma classe de controlar a própria instância.

Introdução aos Padrões de Projeto

Design pattern (ou padrão de projetos) foi originado pela gangue dos quatro (Gang of Four). Décadas depois, padrões de projeto costuma ser uma novidade para programadores. Além de aumentar a qualidade de software com sua unificação de linha lógica de raciocínio, pode também aumentar a produtividade e qualidade do desenvolvimento de software.

A motivação dos padrões de projeto não é deixar os conjuntos de classes menores, mas sim mais flexíveis. Isso facilita muito expansão do sistema no futuro, uma vez 70% do tempo gasto no sistema são de manutenção e extensão. E nos dá o conceito de escalabilidade, que está ligada a capacidade de um sistema de crescer e evoluir.

Podemos resumir o conceito como elementos de códigos que são implementados de acordo com as necessidades que temos no decorrer dos nossos dias como desenvolvedores.

Naturalmente, dividimos os padrões de projeto em três grupos: os padrões criacionais, os estruturais e os comportamentais.

Criacionais : tem a responsabilidade de controlar a instância do objeto, abstraindo e deixando-as independentes de suas classes concretas.

Estruturais : tem a responsabilidade de planejar a estrutura da classe que se está construindo, aumentando a possibilidade de extensão das mesmas sem alteração grandes esforços.

Comportamentais : tem a responsabilidade de controlar comportamentos em tempo de execução.

Nos próximos artigos iremos falar sobre cada um desses tipos e seus padrões. Até a próxima.

Bibliografia:
[GoF] Gamma, Helm, Johnson, Vlissides. Prototype Pattern. Design Patterns — Elements of Reusable Object-Oriented Software, 1995.

Do Factory! - http://www.dofactory.com/

Indiana possui sua certificação aos 9 anos

Para você que estudou no exame para se tornar um MCP, ou pra você que pensa em realizar a prova. Uma indiana, de 9 anos, conseguiu passar o teste, batendo o recorde mundial de um outro garoto de 10 anos.