이 간결한 가이드는 Python 코드 냄새를 해당 디자인 패턴 솔루션에 매핑합니다.
<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>
Python의 리팩토링 예제
이 프로젝트는 Refactoring to Patterns(Joshua Kerievsky)의 리팩토링 예제를 Python으로 변환합니다. 각 예에서는 개선 사항을 강조하는 원본 코드와 리팩터링된 코드를 보여줍니다. 리팩토링 프로세스에는 UML 다이어그램을 해석하고 Java 코드를 Python의 뉘앙스에 맞게 조정하는 작업(순환 가져오기 및 인터페이스 처리)이 포함되었습니다.
예: 작성 방법
"Compose Method" 리팩토링은 더 작고 의미 있는 메서드를 추출하여 복잡한 코드를 단순화합니다.
<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>
예: 다형성(테스트 자동화)
이 예는 재사용성을 위해 테스트 설정을 추상화하여 테스트 자동화의 다형성을 보여줍니다.
<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>
예: 방문자 패턴
방문자 패턴은 클래스와 메소드를 분리합니다.
<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>
결론
리팩토링을 통해 디자인 패턴을 학습하는 이 실용적이고 실무적인 접근 방식은 이해를 크게 향상시킵니다. 코드를 번역하는 동안 직면한 어려움은 이론적 지식을 확고히 합니다.
위 내용은 Python: 패턴으로 리팩토링의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!