ホームページ >バックエンド開発 >Python チュートリアル >Python: パターンへのリファクタリング
この簡潔なガイドでは、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 でのリファクタリングの例
このプロジェクトは、パターンへのリファクタリング (Joshua Kerievsky) のリファクタリング例を Python に翻訳します。各例では、元のコードとリファクタリングされたコードを示し、改善点を強調しています。 リファクタリング プロセスには、UML 図の解釈と、Java コードを Python のニュアンスに適応させる (循環インポートとインターフェイスの処理) ことが含まれていました。
例: Compose メソッド
「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>
例: 訪問者のパターン
Visitor パターンは、クラスをメソッドから切り離します。
<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 中国語 Web サイトの他の関連記事を参照してください。