مفهوم باز-بسته (Open-Closed) در برنامه نویسی و مهندسی نرم افزار

مدرس: مسعود کاویانی

در درس قبل با اولین حرف از اصل SOLID در مهندسی نرم افزار آشنا شدیم. به طور خلاصه: اصل SOLID برای نوشتن نرم افزارهایی با معماری خوب و منعطف برای تغییرات بعدی کاربرد دارد. نرم افزارهای متوسط و بزرگ به دلیل تغییرات زیاد و طول عمر بلند مدت تر، نیاز دارند تا از یک سری اصول مهندسی نرم افزار پیروی کنند. یکی از این اصول SOLID بود.

در این درس به دومین حرف از کلمه SOLID که مفهوم باز-بسته (Open-Closed) است میپردازیم تا ببنیم این اصل چگونه میتواند به نوشتن یک برنامه با کیفیت و منعطف در برابر تغییرات کمک کند.

این اصل یک تعریف ساده دارد:

موجودیت های یک نرم افزار (کلاس ها، توابع و ماژول های مختلف) بایستی در برابر توسعه باز باشند و در برابر تغییرات بسته!

اگر اصل بالا برایتان کمی پیچیده بود، مثالی برایتان داریم: فرض کنید یک کلاس (Class) نوشته اید و در آن کلاس نیز چند تابع (Function) دارید. چند ماهی از شروع توسعه نرم افزار گذشته است و حالا از تیم فروش به شما خبر میرسد که یک ویژگی اضافی احتیاج داریم. شما هم به سراغ کد میروید و میبینید که بایستی در همان کلاس الف قبلی، تابع ب را تغییر دهید. از طرفی هم میخواهید که کد قبلی شما دست نخورده باقی بماند تا ساختار کلی برنامه خراب نشود و یا به کد برنامه نویس قبلی دست نزده باشید! پس در واقع بین یک دو راهی گیر افتاده ایم: ۱. از طرفی نباید به کدهای قدیمی دست زد، زیرا ممکن است جاهای دیگر برنامه که از آن ها استفاده کرده اند خراب شود یا مشکلات دیگری به وجود بیاید ۲. میخواهیم یک قسمت جدید به تابع فعلی اضافه کنیم تا بتوانیم ویژگی مورد نظر تیم فروش را به نرم افزار اضافه کنیم.

برای این راهکار، اصل باز-بسته  به کار میرود و تکنیک های مختلفی که در این اصل وجود دارد. برای غلبه بر مشکل گفته شده در بالا میتوانید از سلسله مراتبی و Inheritance و یا الگو نرم افزار Composite استفاده کنید. ولی برای یک مثال ساده میتوان تکه کد زیر را در نظر گرفت (به زبان PHP)

<?php
class Teacher
{
    public function teach ()
    {
        return 'teach';
    }
}

class Student
{
    public function study ()
    {
        return 'study';
    }
}

class Manager
{
    public function process ($member)
    {
        if  ($member instanceof Teacher) {
            $member->teach ();
        } elseif  ($member instanceof Student) {
            $member->study ();
        }
    }
}
?>

همان طور که در کد بالا مشاهده میکنید، ما سه کلاس داریم. کلاس Teacher که آقای معلم است و کار تدریس را انجام می دهد. کلاس Student که درس میخواند و کلاس Manager که آقای مدیر است و وظیفه مدریت دو موجودیت دیگر را دارد. فرض کنید بعد از مدتی میخواهید یک موجودیت دیگر به نام آقای ناظم به سیستم اضافه کنید که عملیات نظم دادن را انجام میدهد. حتما میدانید که برای این کار علاوه بر ساخت کلاس Monitor که همان آقای ناظم است، باید در کلاس Manger یک if دیگر بگذارید تا چک کند که اگر کلاسی که به مدیر گفته شده از نوع آقای ناظر است، آن وقت تابع نظم دادن را صدا بزند. طبق اصل باز-بسته بودن نرم افزار نباید کلاس Manger دست بخورد. پس تکه کد زیر که تغییر یافته کد بالاست را نگاهی بیندازید:

<?php

interface Workable
{
    public function work ();
}

class Teacher implements Workable
{
    public function work ()
    {
        return 'teach';
    }
}

class Student implements Workable
{
    public function work ()
    {
        return 'study';
    }
}

class Manager
{
    public function process (Workable $member)
    {
        return $member->work ();
    }
}
?>

کمی در کد بالا فکر کنید. یک Interface داریم که دو کلاس آقای معلم و دانش آموز از نوع آن هستند. حتما میدانید که کلاس هایی که از نوع یک Interface حتما باید تمامی توابع آن Interface را داشته باشند. هر کدام از کلاس های آقای معلم و دانش آموز یک تابع work دارند. حال کلاس آقای مدیر را نگاه کنید. این کلاس فقط کافی است که از متغیر member که از نوع Interface Workable است تابع work را صدا بزند. (اگر با کاربرد Interface آشنایی ندارید مثال آن را در گوگل سرچ کنید). حال اگر به کلاس آقای مدیر یک متغیر از نوع آقای معلم نسبت داده شود (یا هر کلاس دیگری) فرقی ندارد، زیرا آقای مدیر فقط تابع work مربوط به آن کلاس را صدا میزند. حتما متوجه شده اید که برای اضافه کردن یک کلاس آقای ناظم فقط کافیست این کلاس از نوع interface Workable باشد و تابع work داشته باشد. آقای ناظم کار خود را در تابع work باید انجام دهد. با این کار دیگر نیازی نیست که در کلاس Manger تغییری ایجاد کنیم.

استفاده از مفهوم Open-closed ساختار برنامه را با کیفیت تر می کند و به برنامه نویسان اجازه میدهد که کدهای خود را به راحتی و بدون توجه به پیامدهای مختلف تغییرات بنویسند. کد نویسی نیز تمیزتر و خواناتر شده و تغییرات بعدی را ساده تر می سازد.

منابع این بحث و اطلاعات بیشتر

» این تکه کد PHP

» وب سایت CodeBurst

» وب سایت tutsplus

در صورت تمایل به یادگیری بیشتر، منابع بالا در نظر گرفته شده است. می توانید با خواندن این منابع، به یادگیری خود در این زمینه عمق ببخشید

یک دیدگاه دربارهٔ «مفهوم باز-بسته (Open-Closed) در برنامه نویسی و مهندسی نرم افزار»

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *