Formatting & Structure

একজন প্রোগ্রামার কোড লেখেন মাত্র একবার, কিন্তু সেই একই কোড মেইনটেইন বা ডিবাগ করার জন্য পড়া হয় শতবার। তাই কোড এমনভাবে ফরম্যাট করা উচিত, যেন চোখে পড়া মাত্রই ব্রেন তা প্রসেস করে ফেলতে পারে। লজিক যতই ভালো হোক না কেন, কোডের Structure বা লেআউট যদি ঠিক না থাকে, তবে সেটি একটি অগোছালো ঘরের (Mess) মতো মনে হয়, যেখানে প্রয়োজনীয় জিনিস খুঁজে পাওয়া প্রায় অসম্ভব।

ক্লিন কোডে ফরম্যাটিং কোনো ঐচ্ছিক বিষয় নয়, এটি পেশাদারিত্বের প্রমাণ।

Structure ও Formatting বলতে কী বোঝায়?

কোডের স্ট্রাকচার এবং ফরম্যাটিং বলতে মূলত বোঝায় কোডের ভিজ্যুয়াল প্রেজেন্টেশন এবং লজিক্যাল অর্গানাইজেশন:

  • Indentation (ইনডেন্টেশন): কোডের ব্লকগুলো কতটুকু স্পেস দিয়ে শুরু হবে।

  • Line Breaks ও Spacing: কোথায় ফাঁকা লাইন দিয়ে কোডগুলোকে আলাদা ব্লকে ভাগ করা হবে।

  • Logical Grouping: সম্পর্কিত কোড বা ভ্যারিয়েবলগুলোকে একসাথে রাখা।

  • Function Ordering: ফাংশনগুলো ফাইলের ভেতর কোন সিরিয়ালে সাজানো থাকবে।

  • Import Structuring: এক্সটার্নাল লাইব্রেরি বা ইন্টারনাল মডিউলগুলো কীভাবে ইমপোর্ট করা হবে।

  • Line Length (অনুভূমিক দৈর্ঘ্য): এক লাইনে সর্বোচ্চ কতগুলো ক্যারেক্টার থাকবে।

  • Consistency: পুরো প্রজেক্ট জুড়ে একই নিয়ম বা স্টাইল গাইড (যেমন: PEP 8) মেনে চলা।

কোড ফরম্যাটিং এর Best Practices

সফটওয়্যার ইঞ্জিনিয়ারিংয়ে পরিচ্ছন্ন স্ট্রাকচার বজায় রাখার জন্য কিছু সুনির্দিষ্ট নিয়ম মেনে চলা হয়:

১. Consistent Indentation (সঠিক ইনডেন্টেশন)

বিশেষ করে পাইথনের মতো ভাষায় ইনডেন্টেশন শুধু সৌন্দর্যের বিষয় নয়, এটি কোডের লজিক নির্ধারণ করে। জাভাতে ব্র্যাকেট {} থাকলেও সঠিক ইনডেন্টেশন ছাড়া কোড পড়া যায় না। স্ট্যান্ডার্ড নিয়ম হলো প্রতি ব্লকের জন্য ৪টি স্পেস ব্যবহার করা।

# Bad: Inconsistent indentation leads to syntax errors and eye strain
def process_data():
  print("Starting process")
    data = load_data()
   return data

# Good: Consistent 4 spaces
def process_data():
    print("Starting process")
    data = load_data()
    return data

২. Vertical Formatting ও Blank Lines (ফাঁকা লাইনের ব্যবহার)

ফাঁকা লাইন বা Blank Line হলো কোডের "নিঃশ্বাস নেওয়ার জায়গা"। একটি বইয়ে যেমন নতুন প্যারাগ্রাফ শুরু হলে একটু ফাঁকা জায়গা থাকে, কোডের ক্ষেত্রেও তেমনি ভিন্ন লজিক্যাল ব্লককে আলাদা করতে ফাঁকা লাইন ব্যবহার করতে হয়।

# Bad: Crowded and hard to read at a glance
def calculate_final_price(base_price: float) -> float:
    tax = base_price * 0.15
    discount = get_seasonal_discount()
    final_price = base_price + tax - discount
    print("Price calculated")
    return final_price


# Good: Logical grouping using blank lines
def calculate_final_price(base_price: float) -> float:
    # Group 1: Gathering dependencies and calculating initial variables
    tax = base_price * 0.15
    discount = get_seasonal_discount()
    
    # Group 2: Core business logic
    final_price = base_price + tax - discount
    
    # Group 3: Side effects (logging) and return statement
    print("Price calculated")
    return final_price


def get_seasonal_discount() -> float:
    # Helper function implementation
    return 50.0

৩. Logical Grouping ও ভ্যারিয়েবল ডিক্লারেশন

যে ভ্যারিয়েবল যেখানে ব্যবহার করা হবে, তাকে ঠিক তার কাছাকাছি ডিক্লেয়ার করা উচিত। অপ্রাসঙ্গিক কাজ (যেমন লগিং) মূল বিজনেস লজিকের মাঝখানে না রেখে আগে বা পরে হ্যান্ডেল করা ভালো।

# Bad: Variables declared far from their usage, mixed concerns
def register_user(user_data):
    db_connection = connect_to_db()
    log_info("Starting registration")
    email = user_data.get("email")
    password = user_data.get("password")
    user_id = db_connection.insert(email, password)
    return user_id

# Good: Grouped by concern and proximity
def register_user(user_data):
    log_info("Starting registration")
    
    email = user_data.get("email")
    password = user_data.get("password")
    
    db_connection = connect_to_db()
    user_id = db_connection.insert(email, password)
    
    return user_id

৪. Import Structuring (ইমপোর্ট সাজানো)

ইমপোর্ট স্টেটমেন্টগুলো এলোমেলোভাবে না লিখে লজিক্যালি তিন ভাগে ভাগ করে লেখা উচিত। এর মাঝখানে একটি করে ফাঁকা লাইন থাকবে।

  1. Standard Library: পাইথন বা জাভার বিল্ট-ইন মডিউল।

  2. Third-party Libraries: বাইরের বা এক্সটার্নাল প্যাকেজ (যেমন: requests, django, spring-boot)।

  3. Local/Internal Modules: নিজের প্রজেক্টের অন্য ফাইল বা মডিউল।

# Standard library imports
import os
import sys
from datetime import datetime

# Third-party imports
import requests
from sqlalchemy import create_engine

# Local application imports
from .models import User
from .utils import validate_email

৫. Function Ordering (Step-down Rule)

ক্লিন কোডের একটি বড় নিয়ম হলো Step-down Rule। এর মানে হলো, কোডটি ওপর থেকে নিচের দিকে একটি খবরের কাগজের আর্টিকেলের মতো পড়া যাবে। যে ফাংশনটি কল করা হচ্ছে (Callee), সেটি সবসময় কলকারী (Caller) ফাংশনের নিচে থাকবে।

# Good Structure following the Step-down rule

def process_checkout(cart):
    validate_cart(cart)
    calculate_total(cart)

# Helper functions placed below the main caller
def validate_cart(cart):
    pass

def calculate_total(cart):
    pass

৬. File Structure ও Line Length

  • ফাইল ভাঙা (Modularization): একটি ফাইলে যখন শত শত লাইন হয়ে যায় এবং ক্লাস বা ফাংশনের সংখ্যা বেড়ে যায়, তখন বুঝতে হবে ফাইলটি একাধিক দায়িত্ব পালন করছে। তখন ফাইলটিকে ভেঙে ছোট ছোট মডিউলে ভাগ করতে হবে (যেমন: validation.py, database.py, helpers.py)।

  • Line Length: এক লাইনে খুব বেশি কোড লিখলে স্ক্রল করে পড়তে হয়, যা বিরক্তিকর। স্ট্যান্ডার্ড নিয়ম হলো এক লাইনে সর্বোচ্চ ৮০ থেকে ১২০ ক্যারেক্টারের মধ্যে সীমাবদ্ধ থাকা।

Formatting Tips Summary

নিয়ম

ভালো অভ্যাস (Best Practices)

Indentation

সর্বত্র ৪ স্পেস ব্যবহার করা (প্রজেক্টে কনসিস্টেন্সি রাখা)।

Imports

Standard → Third-party → Local এই ক্রমানুসারে সাজানো।

Blank lines

কোডের লজিক্যাল সেকশন ব্রেক বা কনসেপ্ট আলাদা করতে ব্যবহার করা।

Function ordering

মূল ফাংশন ওপরে এবং তার হেল্পার ফাংশনগুলো ঠিক তার নিচে রাখা।

File structure

ফাইল বড় ও জটিল হয়ে গেলে ছোট ও ফোকাসড মডিউলে ভাগ করা।

Line Length

এক লাইনে অতিরিক্ত কোড না লিখে ৮০-১২০ ক্যারেক্টারের মধ্যে র‍্যাপ (Wrap) করা।

Consistency

পুরো টিম একই স্টাইল গাইড বা লিন্টার (Linter/Formatter) ব্যবহার করা।

সঠিক স্ট্রাকচার ও ফরম্যাটিং কেবল কোডের সৌন্দর্য বাড়ায় না, এটি টিমের সবার জন্য কোড বোঝার একটি সহজ পথ তৈরি করে দেয়। পরিচ্ছন্ন কোডবেস দেখলে সহজেই বোঝা যায়—কোথায় কী হচ্ছে, কেন হচ্ছে এবং কোনো বাগ থাকলে ঠিক কোথায় খুঁজতে হবে।