abstract چیست؟

دسته بندی: برنامه نویسی
سطح مقاله: پیشرفته
زمان مطالعه: 12 دقیقه
۱۸ اردیبهشت ۱۳۹۸
فارسی
انتزاعی
English
Abstract

در دنیای برنامه نویسی استانداردترین کدها آن هایی هستند که دارای کمترین تکرار کد باشند. اما موقعیت هایی به وجود می آید که ما مجبور می شویم کدهای یکسان را برای انجام کارهای تقریبا یکسان با تغییرات کوچک بارها و بارها بنویسیم. در این وضعیت باید به دنبال راهکارهایی باشیم که این تکرارها را به حداقل ممکن برسانیم. برای مبارزه با این تکرارها از کلاس ها و متدهای abstract یا انتزاعی استفاده می کنیم.

abstract چیست

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

class ChocolateDonut {
    public function make() {
        return $this
            ->makeDough()
            ->moldDonut()
            ->fryDonut()
            ->addChocolate()
            ->packChocolateDonut();
    }

    protected function makeDough() {
        print "make donut dough, first. ";
        return $this;
    }

    protected function moldDonut() {
        print "then, mold donut to have a wheel shape. ";
        return $this;
    }

    protected function fryDonut() {
        print "fry the donut carefully. ";
        return $this;
    }

    protected function addChocolate() {
        print "Add enough chocolate on the donut!";
        return $this;
    }

    protected function packChocolateDonut() {
        print "Pack donut with brown Packing! ";
        return $this;
    }
}

$chocolateDonut = new ChocolateDonut();
$chocolateDonut->make();

برای تهیه دونات با سس توت فرنگی نیز همین مراحل تکرار می شود:

class StrawberryDonut {
    public function make() {
        return $this
            ->makeDough()
            ->moldDonut()
            ->fryDonut()
            ->addStrawberrySauce()
            ->packStrawberryDonut();
    }

    protected function makeDough() {
        print "make donut dough, first. ";
        return $this;
    }

    protected function moldDonut() {
        print "then, mold donut to have a wheel shape. ";
        return $this;
    }

    protected function fryDonut() {
        print "fry the donut carefully. ";
        return $this;
    }

    protected function addStrawberrySauce() {
        print "Add enough strawberry on the donut!";
        return $this;
    }

    protected function packStrawberryDonut() {
        print "Pack donut with pink Packing! ";
        return $this;
    }
}

$strawberryDonut = new StrawberryDonut();
$strawberryDonut->make();

اما گفتیم که نیازی به تکرار کدهای تهیه دونات نیست. چراکه فرآیند تهیه دونات به جز بخش تزئین، یک فرآیند قراردادی و تکراری است. بنابراین بخش های تکراری کد را از طریق استفاده از abstract به یک قرارداد تبدیل می کنیم:

abstract class DonutTemplate {
    public function make() {
        return $this
            ->makeDough()
            ->moldDonut()
            ->fryDonut()
            ->addDressing()
            ->packDonut();
    }

    protected function makeDough() {
        print "make donut dough, first. ";
        return $this;
    }

    protected function moldDonut() {
        print "then, mold donut to have a wheel shape. ";
        return $this;
    }

    protected function fryDonut() {
        print "fry the donut carefully. ";
        return $this;
    }

    protected abstract function addDressing();

    protected abstract function packDonut();
}

class ChocolateDonut extends DonutTemplate {
    protected function addDressing()
    {
        print "Add enough chocolate on the donut!";
        return $this;
    }

    protected function packDonut()
    {
        print "Pack donut with brown Packing! ";
        return $this;
    }
}

class StrawberryDonut extends DonutTemplate {
    protected function addDressing()
    {
        print "Add enough strawberry sauce on the donut!";
        return $this;
    }

    protected function packDonut()
    {
        print "Pack donut with pink Packing! ";
        return $this;
    }
}

$chocoDonut = new ChocolateDonut();
$chocoDonut->make();

همانطور که در کد می بینید، یک کلاس abstract کلاسی است که شامل حداقل یک متد abstract باشد. متدهای abstract متدهایی هستند که فاقد پیاده سازی هستند و فقط کلاس های فرزند را وادار می کنند آن متدها را در خود پیاده سازی کنند. در کد بالا با استفاده از کلمه کلیدی extends کلاس فرزند را وادار کرده ایم از کلاس والد abstract تبعیت کند. در صورتی که کلاس ChocolateDonut، متد addDressing را پیاده سازی نکند، برنامه با ارور مواجه می شود.

از این پس برای ساخت دونات های جدید با هر نوع سس تزئینی، کافی است کلاس دونات جدید، کلاس abstract  با نام DonutTemplate را پیاده سازی نماید.

فهرست محتوای این مقاله

نتیجه گیری

در این مطلب به بررسی abstract و روش استفاده از آن پرداختیم. همانطور که مشاهده کردید، استفاده از این روش خطوط کد را کاهش داده و آن را قانونمند و قابل اعتماد می کند. در کار تیمی، ایجاد قراردادها به سرپرست تیم کمک می کند کدهای یکپارچه دریافت کند. در واقع یکی از کاربرد های اصلی abstract زمانی است که می خواهید توسعه دهندگان تیم خود را مجبور کنید تعدادی متد ایجاد کنند و ترجیح می دهید متدهای آن ها حتما مطابق با ساختارهای تعیین شده از طرف شما باشد. نکته مهم دیگر این است که یک کلاس می تواند چندین interface را پیاده سازی کند ولی فقط از یک کلاس abstract به ارث ببرد. چرا که interface صرفا مجموعه ای از متدهای abstract است. برای آشنایی بیشتر با interface می توانید مقاله ما در مورد interface و کاربرد آن را مطالعه کنید.

نویسنده

نظرات کاربران

پویا راهواره

خیلی روان و عالی بود دمتون گرم

مصطفی

ممنون بابت نکاتی که بیان کردید، اینطور مثال زدن، کار هر کسی نیست. موفق باشید

محمد محبتی

خیلی ممنون خوب بود.

Alireza Shahsavary

ممنون بایت مطالب فوق العادتون ، مثال ها واقعا قابل درک و عالی هستن ♥

زهرا فرحمند

ممنونم لطف دارید جناب شهسواری 🙂

وحید صالحی

و اینگونه هستش که برنامه نویسی شی گرا لذت بخش میشه احسنت.

زهرا فرحمند

ممنونم جناب صالحی عزیز 🙂

حامد

👍👍👍

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :

 
گزارش مشکل