Software Design

Design de software em C, C++, Java, etc…

Python: Instanciando objetos sem saber seu tipo (em tempo de compilação)

Supondo que tenha a seguinte estrutura de classes:

UML

Essa é uma situação bastante comum. Tenho uma classe abstrata que possui várias sub-classes especializadas e minha aplicação precisa decidir em runtime qual delas deverá ser instanciada.

Como tenho uma grande bagagem em linguagens como java/c++, instintivamente pensei em criar um ”’factory method”’ onde eu passaria um int ou string identificando qual tipo será instanciado e receberia como resposta uma nova instância… Algo como:

...

public CopyHandler getCopyHandler(int type, string source, string destination) {
    if ( type == COPY_MODE_FTP ) return new FtpCopyHandler(source, destination)
    else if ( type == COPY_MODE_NFS ) return new NfsCopyHandler(source, destination)
    else if ( type == COPY_MODE_LOCAL ) return new LocalCopyHandler(source, destination)
    else if ( type == COPY_MODE_TFTP ) return new TFtpCopyHandler(source, destination)
    else if ( type == COPY_MODE_SOCKET ) return new SocketCopyHandler(source, destination)
}

Essa função funciona sem maiores problemas, mas onde está a diversão?? Em Python temos um jeito bem mais divertido de fazer isso, dispensando inclusive a necessidade de ter o factory method. Basta criar um dicionário mapeando os tipos ( FTP_COPY_HANDLER / NFS_COPY_HANDLER / etc ) com as classes que serão instanciadas e depois instanciar utilizando o mapa. Ou seja, podemos ter algo assim:

    CopyHandlerDict = { 
        COPY_MODE_LOCAL: LocalCopyHandler,
        COPY_MODE_FTP: FTPCopyHandler,
        COPY_MODE_TFTP: TFTPCopyHandler,
        COPY_MODE_NFS: NFSCopyHandler,
        COPY_MODE_SOCKET: SocketCopyHandler
    }

#... e quando preciso de uma nova instância de um CopyHandler basta:

    handler = CopyHandlerDict[COPY_MODE](source, destination)

Dá pra fazer algo parecido em java utilizando as APIs de reflection para criar novas instâncias dinâmicamente, mas não seria tão simples quanto esse exemplo em Python.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Informação

Publicado às julho 24, 2013 por em Python e marcado , .
%d blogueiros gostam disto: