Eu tenho que projetar e criar um script de importação (em C #) que possa lidar com o seguinte:
- ler dados de várias fontes (XML, XSLX, CSV)
- Verificar dados
- escreva os dados para vários tipos de objetos (cliente, endereço)
Os dados virão de várias fontes, mas uma fonte sempre terá um formato de importação (csv, xml, xslx). Os formatos de importação podem variar de fonte para fonte. Novos formatos de importação podem ser adicionados no futuro. Os tipos de objetos de destino são sempre os mesmos (cliente, endereço e um pouco mais).
Eu tenho pensado em usar genéricos e li algo sobre o padrão de fábrica, mas sou um noob bastante grande nessa área, então qualquer conselho é mais que bem-vindo.
Qual é um padrão de design apropriado para resolver esse problema?
c#
design-patterns
jao
fonte
fonte
Respostas:
Você está exagerando com conceitos extravagantes era muito cedo. Genéricos - quando você vê um caso, use-os, mas não se preocupe. Padrão de fábrica - flexibilidade demais (e confusão adicional) para isso ainda.
Mantenha simples. Use práticas fundamentais.
Tente imaginar as coisas comuns entre fazer uma leitura para XML, uma leitura para CSV, qualquer que seja. Coisas como, próximo registro, próxima linha. Como Novos formatos podem ser adicionados, tente imaginar pontos comuns que o formato a ser determinado teria com os conhecidos. Use essa semelhança e defina uma 'interface' ou contrato que todos os formatos devem aderir. Embora adiram ao terreno comum, todos eles podem ter suas regras internas específicas.
Para validar os dados, tente fornecer uma maneira de conectar facilmente blocos de códigos validadores novos ou diferentes. Então, novamente, tente definir uma interface em que cada validador, responsável por um tipo específico de construção de dados, adira a um contrato.
Para criar as construções de dados, você provavelmente será restringido por quem projetar os objetos de saída sugeridos mais do que qualquer coisa. Tente descobrir qual é o próximo passo para os objetos de dados e há alguma otimização que você possa fazer sabendo o uso final. Por exemplo, se você souber que os objetos serão usados em um aplicativo interativo, poderá ajudar o desenvolvedor desse aplicativo fornecendo 'somatórios' ou contagens dos objetos ou outros tipos de informações derivadas.
Eu diria que a maioria destes são padrões de modelo ou padrões de estratégia. Todo o projeto seria um padrão de adaptador.
fonte
O óbvio é aplicar o padrão de estratégia . Tenho uma classe base genérico
ReadStrategy
e para cada formato de entrada uma subclasse comoXmlReadStrategy
,CSVReadStrategy
etc. Isso permitirá que você mude o processamento de importação de forma independente a partir do processamento VERIFICAÇÃO eo processamento de saída.Dependendo dos detalhes, também pode ser possível manter a maioria das partes da importação genérica e trocar apenas partes do processamento de entrada (por exemplo, leitura de um registro). Isso pode levar você ao padrão do método de modelo .
fonte
Um padrão adequado para um utilitário de importação que talvez você precise estender no futuro seria usar o MEF - você pode manter o uso de memória baixo carregando o conversor necessário em tempo real a partir de uma lista lenta, criar importações de MEF decoradas com atributos que ajudam a selecionar o conversor certo para a importação que você está tentando executar e fornece uma maneira fácil de separar as diferentes classes de importação.
Cada parte do MEF pode ser construída para satisfazer uma interface de importação com alguns métodos padrão que convertem uma linha do arquivo de importação em seus dados de saída ou substituem uma classe base pela funcionalidade básica.
O MEF é uma estrutura para criar uma arquitetura de plug-in - é como o Outlook e o Visual Studio são criados, todas essas extensões adoráveis no VS são partes do MEF.
Para criar um aplicativo MEF (Managed Extensability Framework), comece incluindo uma referência a
System.ComponentModel.Composition
Definir interfaces para especificar o que o conversor fará
Isso pode ser usado para todos os tipos de arquivos que você deseja importar.
Adicione atributos a uma nova classe que defina o que a classe "Exportará"
Isso definiria uma classe que importará arquivos CSV (de um formato específico: Format1) e possui atributos personalizados que configuram os metadados do atributo de exportação MEF. Você repetiria isso para cada formato ou tipo de arquivo que deseja importar. Você pode definir atributos personalizados com uma classe como:
Para realmente usar os conversores MEF, você precisa importar as partes que você cria quando o código de conversão é executado:
catalog
coleta as partes de uma pasta, o padrão é o local do aplicativo.converters
é uma lista lenta das peças importadas do MEFEntão, quando você souber que tipo de arquivo deseja converter (
importFileType
eimportType
), obtenha um conversor na lista de peças importadas emconverters
A chamada para
converter.ImportData
usará o código na classe importada.Pode parecer muito código e pode demorar um pouco para você entender o que está acontecendo, mas é extremamente flexível quando se trata de adicionar novos tipos de conversor e pode até permitir que você adicione novos durante o tempo de execução.
fonte
-1
porque a ideia subjacente ainda faz sentido e depende de um padrão de estratégia governado pelaIImportConverter
interface.Os idiomas C # envolvem o uso da estrutura de serialização incorporada para fazer isso. Você anota os objetos com metadados e, em seguida, instancia serializadores diferentes que usam essas anotações para extrair dados para colocar na forma correta ou vice-versa.
Os formulários XML, JSON e binários são os mais comuns, mas não ficaria surpreso se outros já existirem em um bom formulário compactado para você consumir.
fonte