1
resposta

Minha Solucao para o mao na maca

from abc import ABC, abstractmethod
import time

class Document(ABC):
    def __init__(self, title):
        self.title = title

    @abstractmethod
    def generate_content(self):
        """Creates content"""
        pass

    @abstractmethod
    def export(self):
        """Exports creates content"""
        pass

class PlainTextDocument(Document):
    def generate_content(self, text):
        self.content = text
        return self.content
    
    def export(self):
        doc = self.title
        return f"{doc}.txt"
    
class HTMLDocument(Document):
    def generate_content(self, text):
        self.content = text
        return self.content
    
    def export(self):
        doc = self.title
        return f"{doc}.html"
    
class CSVDocument(Document):
    def generate_content(self, text):
        self.content = text
        return self.content
    
    def export(self):
        doc = self.title
        return f"{doc}.csv"

class DocumentCreator(ABC):

    @abstractmethod
    def create_document(self, title):
        pass

    def export_document(self, title, text):
        """
        Fluxo padronizado:
        * Criar o documento (via Factory Method)
        * Gerar o conteúdo
        * Exportar
        """
        doc = self.create_document(title)
        doc.generate_content(text)
        return doc.export()
    
class PlainTextDocumentCreator(DocumentCreator):
    def create_document(self, title):
        return PlainTextDocument(title)
    
class HTMLDocumentCreator(DocumentCreator):
    def create_document(self, title):
        return HTMLDocument(title)
    
class CSVDocumentCreator(DocumentCreator):
    def create_document(self, title):
        return CSVDocument(title)
    


class FabricaDeArquivo:
    @staticmethod
    def criar_arquivo(tipo):
        if tipo == "txt":
            return PlainTextDocumentCreator()
        elif tipo == "html":
            return HTMLDocumentCreator()
        elif tipo == "csv":
            return CSVDocumentCreator()
        else:
            raise ValueError("Tipo de arquivo invalido.")
        
class ServicoCriarArquivo:
    def __init__(self, tipo_arquivo):
        self.arquivo = FabricaDeArquivo.criar_arquivo(tipo_arquivo)

    def export(self, title, text):
        return self.arquivo.export_document(title, text)
    

def coletar_arquivo():
    tipo_arquivo = input("Digite o tipo de arquivo que deseja criar (txt, html ou csv): ").lower()
    titulo_arquivo = input("Digite o titulo do arquivo: ")
    conteudo_arquivo = input("Digite o conteudo do arquivo: ")
    print("\n")

    arquivo = ServicoCriarArquivo(tipo_arquivo)
    print("Criando arquivo \n")
    time.sleep(2)
    print(arquivo.export(titulo_arquivo, conteudo_arquivo))

if __name__ == "__main__":
    try:
        coletar_arquivo()
    except ValueError as e:
        print(f"Error: {e}")

Essa foi a forma que usei prar solucionar o desafio, o que acham? Tem alguma coisa ai que consideram errado, ou que esta se repetindo e n~ao deveria?

1 resposta

Oii, Paula!

Parabéns por concluir a atividade Mão na massa: Factory Method. Ficou nítido como você organizou a estrutura do seu código para aplicar os conceitos de orientação a objetos, segmentando as responsabilidades de criação e comportamento de forma direta e objetiva.

A sua solução está muito bem desenvolvida e demonstra que você compreendeu o propósito do padrão Factory Method. O grande destaque do seu código é a classe abstrata DocumentCreator e seu método export_document. Ao definir um fluxo padronizado que cria, gera conteúdo e exporta o documento, você aplicou com perfeição a essência do padrão: delegar a heranças específicas a decisão de qual objeto exato instanciar, mantendo o algoritmo principal intacto.

A estrutura geral tá correta e funciona perfeitamente. Respondendo à sua dúvida sobre repetições ou pontos de melhoria, existem dois aspectos na arquitetura atual que podem ser refinados para deixar o código ainda mais limpo:

1. Repetição do método generate_content

Se você reparar nas classes PlainTextDocument, HTMLDocument e CSVDocument, o método generate_content faz exatamente a mesma coisa em todas elas:

def generate_content(self, text):
    self.content = text
    return self.content

Como esse comportamento não muda entre os tipos de documento, você não precisa declará-lo como um @abstractmethod e repetir o código em todas as subclasses. O ideal é movê-lo diretamente para a classe base Document. Assim, as subclasses herdam essa mecânica automaticamente, eliminando a repetição.

2. Duplicidade de padrões (Factory Method + Simple Factory)

No seu código, você implementou a estrutura completa do Factory Method (com os criadores abstratos e concretos) e, logo depois, criou a classe FabricaDeArquivo com o método estático criar_arquivo, que funciona como uma Simple Factory.

No dia a dia do desenvolvimento, quando usamos o Factory Method, a escolha de qual criador usar costuma ser feita diretamente pelo cliente ou injetada por configuração, sem a necessidade de passar por uma segunda fábrica de decisões com blocos if/elif. Se a ideia era ter uma classe centralizadora como a FabricaDeArquivo para avaliar o texto digitado ("txt", "html"), você poderia conectar essa fábrica de strings diretamente aos produtos (PlainTextDocument, HTMLDocument), sem precisar criar a hierarquia de classes DocumentCreator. Ter as duas estruturas juntas traz uma complexidade extra ao código que pode ser simplificada.

Você possui uma ótima base de lógica e está avançando firmemente no entendimento de arquitetura de software e padrões de projeto.

Na sua visão, remover a hierarquia de DocumentCreator e manter apenas a FabricaDeArquivo instanciando os documentos diretamente deixaria o sistema mais simples de dar manutenção caso novos formatos fossem adicionados?

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!