الأنماط المضادة: ما لا يجب فعله
6 دقائق قراءة
شرائح الدرس
1 / 15
الأنماط المضادة (Anti-Patterns) هي استجابات شائعة لمشكلات متكررة، لكنها عادةً ما تكون غير فعّالة وتؤدي إلى نتائج عكسية. فهم الأنماط المضادة لا يقل أهمية عن معرفة أنماط التصميم نفسها.
الأنماط المضادة الخاصة بأنماط التصميم
graph TD
A[Anti-Patterns] --> B[Misuse of Patterns]
A --> C[Architectural Anti-Patterns]
A --> D[Code-Level Anti-Patterns]
B --> B1[Golden Hammer]
B --> B2[Pattern Obsession]
B --> B3[Copy-Paste Programming]
C --> C1[Big Ball of Mud]
C --> C2[Spaghetti Code]
C --> C3[God Object]
D --> D1[Magic Numbers]
D --> D2[Dead Code]
D --> D3[Duplicate Code]1. الأنماط المضادة الخاصة بكل نمط
الأنماط المضادة لـ Singleton
# ❌ ANTI-PATTERN: Singleton Abuse
class ConfigManager: # Everything becomes singleton
_instance = None
# ... singleton implementation
class DatabaseManager: # Another singleton
_instance = None
# ... singleton implementation
class LogManager: # Yet another singleton
_instance = None
# ... singleton implementation
# Problems: Global state, testing difficulties, tight coupling# ✅ BETTER APPROACH: Dependency Injection
class OrderService:
def __init__(self, config, db, logger):
self.config = config
self.db = db
self.logger = logger
def process_order(self, order):
# Use injected dependencies
passالأنماط المضادة لـ Factory
# ❌ ANTI-PATTERN: God Factory
class EverythingFactory:
def create_object(self, type, subtype, variant, options):
if type == "user":
if subtype == "admin":
if variant == "super":
# 50 lines of creation logic
elif variant == "regular":
# 30 lines of creation logic
elif subtype == "regular":
# ... more nested conditions
elif type == "product":
# ... another 100 lines
# This factory does too much!# ✅ BETTER APPROACH: Specialized Factories
class UserFactory:
def create_admin(self, level): pass
def create_regular_user(self): pass
class ProductFactory:
def create_physical_product(self): pass
def create_digital_product(self): pass2. الأنماط المضادة المعمارية
الكائن الإله (The God Object)
classDiagram
class GodObject {
+processUser()
+handlePayment()
+sendEmail()
+validateData()
+generateReport()
+manageInventory()
+calculateTax()
+logActivity()
+... 50 more methods
}
note for GodObject "Violates Single Responsibility Principle"كرة الطين الكبيرة (Big Ball of Mud)
يشير هذا النمط المضاد إلى معمارية أو تصميم برمجي يفتقر إلى البنية والتنظيم والفصل الواضح بين المهام. في معمارية "كرة الطين الكبيرة"، تتطور قاعدة الكود عادةً بمرور الوقت دون رؤية معمارية متماسكة أو قرارات تصميم فعّالة. والنتيجة أن النظام يصبح أكثر تعقيدًا وتشابكًا، ويصعب فهمه وصيانته وتوسيعه.
graph LR
A[Module A] -.-> B[Module B]
B -.-> C[Module C]
C -.-> A
A -.-> D[Module D]
D -.-> E[Module E]
E -.-> B
C -.-> F[Module F]
F -.-> A
E -.-> F
style A fill:#ff9999
style B fill:#ff9999
style C fill:#ff9999
style D fill:#ff9999
style E fill:#ff9999
style F fill:#ff99993. أنماط تصميم مضادة شائعة أخرى
الأرقام والنصوص السحرية (Magic Numbers and Strings)
# ❌ ANTI-PATTERN: Magic Numbers
def calculate_discount(price):
if price > 1000:
return price * 0.15 # What does 0.15 mean?
elif price > 500:
return price * 0.10 # What does 0.10 mean?
return 0
def get_user_type(code):
if code == 1: # What does 1 mean?
return "admin"
elif code == 2: # What does 2 mean?
return "user"# ✅ BETTER APPROACH: Named Constants
class DiscountRates:
PREMIUM_THRESHOLD = 1000
PREMIUM_RATE = 0.15
STANDARD_THRESHOLD = 500
STANDARD_RATE = 0.10
class UserTypes:
ADMIN = 1
REGULAR_USER = 2
def calculate_discount(price):
if price > DiscountRates.PREMIUM_THRESHOLD:
return price * DiscountRates.PREMIUM_RATE
elif price > DiscountRates.STANDARD_THRESHOLD:
return price * DiscountRates.STANDARD_RATE
return 0برمجة النسخ واللصق (Copy-Paste Programming)
# ❌ ANTI-PATTERN: Duplicate Code
def process_order_email(order):
subject = f"Order {order.id} Confirmation"
body = f"Dear {order.customer.name}, your order has been processed"
send_email(order.customer.email, subject, body)
def process_shipment_email(order):
subject = f"Order {order.id} Shipped" # Similar code
body = f"Dear {order.customer.name}, your order has been shipped" # Similar code
send_email(order.customer.email, subject, body) # Duplicate
def process_delivery_email(order):
subject = f"Order {order.id} Delivered" # Similar code again
body = f"Dear {order.customer.name}, your order has been delivered" # Similar code again
send_email(order.customer.email, subject, body) # More duplication# ✅ BETTER APPROACH: Template Method Pattern
class EmailNotification:
def send_order_notification(self, order, event_type):
subject = self._create_subject(order, event_type)
body = self._create_body(order, event_type)
send_email(order.customer.email, subject, body)
def _create_subject(self, order, event_type):
return f"Order {order.id} {event_type.title()}"
def _create_body(self, order, event_type):
messages = {
'confirmation': 'has been processed',
'shipped': 'has been shipped',
'delivered': 'has been delivered'
}
return f"Dear {order.customer.name}, your order {messages[event_type]}"4. قائمة تدقيق لاكتشاف الأنماط المضادة
flowchart TD
A[Code Review] --> B{Class > 500 lines?}
B -->|Yes| C[Possible God Object]
B -->|No| D{Method > 50 lines?}
D -->|Yes| E[Extract Methods]
D -->|No| F{Duplicate Code?}
F -->|Yes| G[Apply DRY Principle]
F -->|No| H{Magic Numbers?}
H -->|Yes| I[Extract Constants]
H -->|No| J{Tight Coupling?}
J -->|Yes| K[Apply SOLID Principles]
J -->|No| L[Code Looks Good!]5. إعادة هيكلة الأنماط المضادة
قبل: مثال على النمط المضاد
class OrderProcessor: # God Object Anti-Pattern
def process_order(self, order_data):
# Validation (should be separate)
if not order_data.get('email'):
raise ValueError("Email required")
# Payment processing (should be separate)
if order_data['payment_method'] == 'credit_card':
# 20 lines of credit card logic
pass
elif order_data['payment_method'] == 'paypal':
# 15 lines of PayPal logic
pass
# Inventory management (should be separate)
for item in order_data['items']:
# 10 lines of inventory logic
pass
# Email notification (should be separate)
# 15 lines of email logic
# Logging (should be separate)
# 5 lines of logging logicبعد: التطبيق الصحيح للأنماط
class OrderProcessor:
def __init__(self, validator, payment_processor, inventory, notifier, logger):
self.validator = validator
self.payment_processor = payment_processor
self.inventory = inventory
self.notifier = notifier
self.logger = logger
def process_order(self, order_data):
self.validator.validate(order_data)
payment_result = self.payment_processor.process(order_data)
self.inventory.reserve_items(order_data['items'])
self.notifier.send_confirmation(order_data)
self.logger.log_order_processed(order_data)
return payment_resultإرشادات الوقاية من الأنماط المضادة
- مبدأ المسؤولية الواحدة (Single Responsibility): يجب أن يكون لكل فئة سبب واحد فقط للتغيير
- تجنّب الحالة العامة (Global State): قلّل من استخدام الـ Singletons والمتغيرات العامة
- فضّل التركيب (Composition) على الوراثة: استخدم حقن التبعيات بدلًا من الوراثة المفرطة
- حافظ على البساطة: لا تفرط في هندسة الحلول
- إعادة الهيكلة المنتظمة: حسّن بنية الكود باستمرار
- مراجعات الكود: اطلب من الآخرين مراجعة استخدامك للأنماط
- التطوير المُوجَّه بالاختبارات (TDD): اكتب اختبارات لاكتشاف مشكلات التصميم مبكرًا