Maison > développement back-end > Tutoriel Python > Python : refactorisation vers des modèles

Python : refactorisation vers des modèles

Susan Sarandon
Libérer: 2025-01-16 13:10:58
original
897 Les gens l'ont consulté

Python: Refactoring to Patterns

Photo de Patric Ho

Ce guide concis mappe les odeurs du code Python aux solutions de modèles de conception correspondantes.

<code class="language-python">class CodeSmellSolutions:
    DUPLICATED_CODE = [
        "form_template_method",
        "introduce_polymorphic_creation_with_factory_method",
        "chain_constructors",
        "replace_one__many_distinctions_with_composite",
        "extract_composite",
        "unify_interfaces_with_adapter",
        "introduce_null_object",
    ]
    LONG_METHOD = [
        "compose_method",
        "move_accumulation_to_collecting_parameter",
        "replace_conditional_dispatcher_with_command",
        "move_accumulation_to_visitor",
        "replace_conditional_logic_with_strategy",
    ]
    CONDITIONAL_COMPLEXITY = [  # Complex conditional logic
        "replace_conditional_logic_with_strategy",
        "move_emblishment_to_decorator",
        "replace_state_altering_conditionals_with_state",
        "introduce_null_object",
    ]
    PRIMITIVE_OBSESSION = [
        "replace_type_code_with_class",
        "replace_state_altering_conditionals_with_state",
        "replace_conditional_logic_with_strategy",
        "replace_implict_tree_with_composite",
        "replace_implicit_language_with_interpreter",
        "move_emblishment_to_decorator",
        "encapsulate_composite_with_builder",
    ]
    INDECENT_EXPOSURE = [  # Lack of information hiding
        "encapsulate_classes_with_factory"
    ]
    SOLUTION_SPRAWL = [  # Scattered logic/responsibility
        "move_creation_knowledge_to_factory"
    ]
    ALTERNATIVE_CLASSES_WITH_DIFFERENT_INTERFACES = [  # Similar classes, different interfaces
        "unify_interfaces_with_adapter"
    ]
    LAZY_CLASS = [  # Insufficient functionality
        "inline_singleton"
    ]
    LARGE_CLASS = [
        "replace_conditional_dispatcher_with_command",
        "replace_state_altering_conditionals_with_state",
        "replace_implict_tree_with_composite",
    ]
    SWITCH_STATEMENTS = [  # Complex switch statements
        "replace_conditional_dispatcher_with_command",
        "move_accumulation_to_visitor",
    ]
    COMBINATION_EXPLOSION = [  # Similar code for varying data
        "replace_implicit_language_with_interpreter"
    ]
    ODDBALL_SOLUTIONS = [  # Multiple solutions for same problem
        "unify_interfaces_with_adapter"
    ]</code>
Copier après la connexion

Exemples de refactoring en Python

Ce projet traduit des exemples de refactoring de Refactoring to Patterns (Joshua Kerievsky) en Python. Chaque exemple montre du code original et refactorisé, mettant en évidence les améliorations. Le processus de refactoring impliquait l'interprétation des diagrammes UML et l'adaptation du code Java aux nuances de Python (gestion des importations et des interfaces cycliques).

Exemple : Méthode Compose

La refactorisation « Compose Method » simplifie le code complexe en extrayant des méthodes plus petites et plus significatives.

<code class="language-python"># Original (complex) code
def add(element):
    readonly = False
    size = 0
    elements = []
    if not readonly:
        new_size = size + 1
        if new_size > len(elements):
            new_elements = []
            for i in range(size):
                new_elements[i] = elements[i]  # Potential IndexError
            elements = new_elements
        size += 1
        elements[size] = element # Potential IndexError

# Refactored (simplified) code
def is_at_capacity(new_size, elements):
    return new_size > len(elements)

def grow_array(size, elements):
    new_elements = [elements[i] for i in range(size)] # List comprehension for clarity
    return new_elements

def add_element(elements, element, size):
    elements.append(element) # More Pythonic approach
    return len(elements) -1

def add_refactored(element):
    readonly = False
    if readonly:
        return
    size = len(elements)
    new_size = size + 1
    if is_at_capacity(new_size, elements):
        elements = grow_array(size, elements)
    size = add_element(elements, element, size)

</code>
Copier après la connexion

Exemple : Polymorphisme (automatisation des tests)

Cet exemple démontre le polymorphisme dans l'automatisation des tests, en faisant abstraction de la configuration des tests pour la réutilisabilité.

<code class="language-python"># Original code (duplicate setup)
class TestCase:
    pass

class DOMBuilder:
    def __init__(self, orders): pass
    def calc(self): return 42

class XMLBuilder:
    def __init__(self, orders): pass
    def calc(self): return 42

class DOMTest(TestCase):
    def run_dom_test(self):
        expected = 42
        builder = DOMBuilder("orders")
        assert builder.calc() == expected

class XMLTest(TestCase):
    def run_xml_test(self):
        expected = 42
        builder = XMLBuilder("orders")
        assert builder.calc() == expected

# Refactored code (polymorphic setup)
class OutputBuilder:
    def calc(self): raise NotImplementedError

class DOMBuilderRefac(OutputBuilder):
    def calc(self): return 42

class XMLBuilderRefac(OutputBuilder):
    def calc(self): return 42

class TestCaseRefac:
    def create_builder(self): raise NotImplementedError
    def run_test(self):
        expected = 42
        builder = self.create_builder()
        assert builder.calc() == expected

class DOMTestRefac(TestCaseRefac):
    def create_builder(self): return DOMBuilderRefac()

class XMLTestRefac(TestCaseRefac):
    def create_builder(self): return XMLBuilderRefac()
</code>
Copier après la connexion

Exemple : modèle de visiteur

Le modèle Visiteur dissocie les classes de leurs méthodes.

<code class="language-python"># Original code (conditional logic in TextExtractor)
class Node: pass
class LinkTag(Node): pass
class Tag(Node): pass
class StringNode(Node): pass

class TextExtractor:
    def extract_text(self, nodes):
        result = []
        for node in nodes:
            if isinstance(node, StringNode): result.append("string")
            elif isinstance(node, LinkTag): result.append("linktag")
            elif isinstance(node, Tag): result.append("tag")
            else: result.append("other")
        return result

# Refactored code (using Visitor)
class NodeVisitor:
    def visit_link_tag(self, node): return "linktag"
    def visit_tag(self, node): return "tag"
    def visit_string_node(self, node): return "string"

class Node:
    def accept(self, visitor): pass

class LinkTagRefac(Node):
    def accept(self, visitor): return visitor.visit_link_tag(self)

class TagRefac(Node):
    def accept(self, visitor): return visitor.visit_tag(self)

class StringNodeRefac(Node):
    def accept(self, visitor): return visitor.visit_string_node(self)

class TextExtractorVisitor(NodeVisitor):
    def extract_text(self, nodes):
        result = [node.accept(self) for node in nodes]
        return result
</code>
Copier après la connexion

Conclusion

Cette approche pratique et pratique de l'apprentissage des modèles de conception grâce à la refactorisation améliore considérablement la compréhension. Les défis rencontrés lors de la traduction du code solidifient les connaissances théoriques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal