مثال رابط برای PHP شی گرا

Interface Examples For Object Oriented PHP – Vegibit

در این آموزش ، ما در برنامه نویسی در Object Oriented PHP نگاهی به مثالهای رابط می اندازیم. رابط ها یکی از اصلی ترین عناصر سازنده الگوی SOLID هستند. هنگامی که من برای اولین بار کلمه SOLID را دیدم ، مانند کسی که به برنامه نویسی SOLID اشاره داشت ، فکر کردم که منظور آن جامد است ، همانطور که در خنک یا مجاز است. هاها. یا البته در واقعیت ، SOLID ایده ِ گروهی از الگوهای طراحی ، قراردادها و فلسفه های محبوب عمو باب مارتین است. اینها اصل مسئولیت منفرد ، باز بسته ، تعویض لیسکوف ، تفکیک رابط و وارونگی وابستگی است. ما تمام این ایده ها را به جلو حرکت خواهیم داد. در حال حاضر ، بیایید اطمینان حاصل کنیم که ایده یک رابط در هنگام برنامه نویسی شی گرا در ماده خاکستری ما کاملاً محکم شده است.

رابط چیست؟

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

Interface Syntax

کد یک رابط تقریباً شبیه تعریف کلاس است. به جای استفاده از کلمه کلیدی class ، ما به سادگی هنگام کدگذاری از کلمه کلیدی interface استفاده می کنیم. علاوه بر این ، متدهایی که ما در رابط کاربری تعریف می کنیم هیچ آکولادی {} ندارند، زیرا منطقی وجود ندارد که در آکولاد قرار دهیم. بیایید مثالی از رابط را ببینیم.

interface Lawnmower {
public function cut_grass();
}

خودشه. خیلی هیجان انگیزه!نه؟ 🙂

اجرای یک رابط

ما یک رابط برای اجرای رفتار اجرا می کنیم. در نظر داشته باشید که در حال خرید ماشین چمن زنی (Lawnmower) جدید هستید. شما آن را به سه مدل محدود کرده اید. یکی از کوبوتا ، یکی از جان دیر ، و یکی از کراپیمورس. دو مورد از اینها رابط چمن زنی را اجرا می کنند ، به این معنی که تضمین شده اند قادر به cut_grass() هستند. مورد سوم رابط Lawnmower را اجرا نمی کند. بیایید در کد ما به خرید ماشین چمن زنی برویم.

<?php

interface Lawnmower {
public function cut_grass();
}

// does not implement
class CrappyMowersInc {
public function leak_oil() {
return 'leaking oil';
}
}
$mower = new CrappyMowersInc;

var_dump($mower->leak_oil()); // leaking oil

class Kubota implements Lawnmower {
public function cut_grass(){
return 'cutting major grass';
}
}
$mower = new Kubota;
var_dump($mower->cut_grass()); // cutting major grass

class JohnDeere implements Lawnmower {
public function cut_grass(){
return 'cutting grass like a champion';
}
}
$mower = new JohnDeere;
var_dump($mower->cut_grass()); // cutting grass like a champion

همانطور که در اینجا می بینیم ، دو مدلی که رابط صحیح را پیاده سازی می کنند ، همان مدل هایی هستند که ما دوست داریم. علاوه بر این ، از آنجا که هر دو کلاس مورد علاقه ما رابط چمن زنیLawnmower خود را implement یا پیاده سازی می کنند ، اساساً قابل تعویض هستند. بنابراین اگر با کوبوتا یا جاندیر بروید ، تفاوت زیادی ایجاد نمی کند ، هر دو چمن شما را به خوبی برش می دهند. از طرف دیگر CrappyMowersInc رابط کاربری Lawnmower ما را اجرا نمی کند و بنابراین نتیجه مورد نظر ما را فراهم نمی کند.

Program To an Interface

اکنون به ایده دیگری در رابطه با رابط ها رسیده ایم و آن برنامه ریزی برای یک رابط است ، نه پیاده سازی. معنی آن این است که اگر کلاسی دارید که برای انجام یک کار باید چندین راه مختلف داشته باشید ، می توانید یک رابط ایجاد کنید. بیایید یک شرکت محوطه سازی را تصور کنیم که قصد دارد از ماشین های چمن زنی ما استفاده کند. این شرکت نیاز به برش چمن های مشتریان خود دارد. مهم نیست که آنها این کار را با JohnDeere ، Kubota ، push mower یا یک قیچی انجام می دهند. تا زمانی که کار را به درستی انجام دهند مشتری خوشحال خواهد شد. در ابتدا ، بیایید یک کلاس Landscaper (محوطه سازی) ایجاد کنیم که برای برش چمن ها از JohnDeere استفاده می کند.


class Landscaper
{
protected $mower;
protected $customer;

public function __construct(JohnDeere $mower, $customer = ''){
$this->mower = $mower;
$this->customer = $customer;
}

public function help_customer(){
return 'Finished mowing '. $this->customer .' lawn';
}
}

$landscaper = new Landscaper(new JohnDeere, 'The Johnsons');
var_dump($landscaper->help_customer());
// string 'Finished mowing The Johnsons lawn' (length=33)

$landscaper = new Landscaper(new JohnDeere, 'The Thompsons');
var_dump($landscaper->help_customer());
// string 'Finished mowing The Thompsons lawn' (length=34)

همه چیز عالی پیش می رود. ما امروز به دو مشتری کمک کرده ایم و آنها هیجان زده شده اند. متأسفانه ، تیغه JohnDeere ما به سنگ برخورد کرده و اکنون آسیب دیده است. ما قطعات یدکی نداریم ، بنابراین به نظر می رسد برای اتمام آخرین کار روز باید از نسخه پشتیبان Kubota استفاده کنیم. اجازه دهید آن را امتحان کنید.


$landscaper = new Landscaper(new Kubota, 'The Henrys');
var_dump($landscaper->help_customer());
// Catchable fatal error: Argument 1 passed to Landscaper::__construct() must be an instance of JohnDeere, instance of Kubota given

🙁 وای نه! مشتری ها از اینکه ما قادر به پایان کار نیستیم ناراحت هستند. مسئله این است که ما در یک طبقه بندی یا پیاده سازی به سازنده کلاس Landscaping منتقل شدیم. در عوض ، ما باید برای یک رابط برنامه نویسی می کردیم. به این ترتیب می توانیم جان دیر را با یک کوبوتا عوض کنیم و بسیار خوب کار خواهد کرد. دلیل اینکه کاملا خوب کار خواهد کرد این است که هم کلاس JohnDeere و هم کلاس Kubota از رابط یکسانی استفاده می کنند. این بدان معنی است که آنها می توانند همان رفتار دقیق را انجام دهند ، که در اینجا cut_grass() است. بیایید کد خود را به روز کنیم تا انعطاف پذیرتر باشد.بایید این تغییر کوچک را که در کلاس Landscaper ایجاد کرده ایم ، بررسی کنید.


interface Lawnmower {
public function cut_grass();
}

class Kubota implements Lawnmower {
public function cut_grass(){
return 'cutting major grass';
}
}

class JohnDeere implements Lawnmower {
public function cut_grass(){
return 'cutting grass like a champion';
}
}

class Landscaper
{
protected $mower;
protected $customer;

public function __construct(Lawnmower $mower, $customer = ''){
$this->mower = $mower;
$this->customer = $customer;
}

public function help_customer(){
return 'Finished mowing '. $this->customer .' lawn';
}
}

$landscaper = new Landscaper(new JohnDeere, 'The Johnsons');
var_dump($landscaper->help_customer());
// string 'Finished mowing The Johnsons lawn' (length=33)

$landscaper = new Landscaper(new JohnDeere, 'The Thompsons');
var_dump($landscaper->help_customer());
// string 'Finished mowing The Thompsons lawn' (length=34)

$landscaper = new Landscaper(new Kubota, 'The Henrys');
var_dump($landscaper->help_customer());
// string 'Finished mowing The Henrys lawn' (length=31)

 

توجه داشته باشید که ما اکنون از طریق یک رابط وارد سازنده کلاس Landscaper می شویم. حالا وقتی بعداً آن کلاس را در کد مشتری خود وارد کردیم ، می توانیم از یک JohnDeere یا یک Kubota استفاده کنیم و هیچ کس سر و صدا نمی کند! برای کلاس دیگر مهم نیست که چه چیزی به آن می دهید ، یا اینکه چگونه کار خود را به پایان می رساند. تا زمانی که بتواند کار را به اتمام برساند ، که در این حالت بریدن چمن است ، همه چیز جواب می دهد. باور نمی کنید؟ اجازه دهید خدمه Landscaping با یک قیچی چمن ها را برش دهند.

<?php

class Scissors implements Lawnmower {
public function cut_grass(){
return 'Finished cutting the grass in 14.2 hours.';
}
}

class Landscaper
{
protected $mower;
protected $customer;

public function __construct(Lawnmower $mower, $customer = ''){
$this->mower = $mower;
$this->customer = $customer;
}

public function help_customer(){
return 'Finished mowing '. $this->customer .' lawn';
}
}

$landscaper = new Landscaper(new Scissors, 'The McFlys');
var_dump($landscaper->help_customer());
// string 'Finished mowing The McFlys lawn' (length=31)

برنامه نویسی Concretion در مقابل برنامه نویسی Interface

برای توضیح بیشتر نحوه عملکرد ، اجازه دهید از منظر کلاس Landscaper به این موضوع نگاه کنیم. در اولین مثال خود ، ما به یک برنامه نویسی غیرانعطاف (concretion) می کنیم. ما می توانیم این را ببینیم زیرا ما به JohnDeere که یک کلاس بتنی است (یک کلاس واقعی با منطق که کاری انجام می دهد) پاس داده میشویم. این بدان معنی است که کلاس Landscaper به جهانیان می گوید ، “هی ، من برای انجام کار خود به یک JohnDeere نیاز دارم. یک کوبوتا ، یا یک صنعتگر ، یا یک هوندا ، یا یک Pushmower یا یک قیچی به من ندهید. اگر غیر از JohnDeere به من چیز دیگری بدهید ، من قصد دارم کلاهبرداری کنم. ”

البته این انعطاف پذیرترین راه حل در جهان نیست. در مثال دوم ، ما رابط را برنامه ریزی می کنیم. این بدان معناست که ما به جای بتن از یک رابط به سازنده می رسیم. این آنچه کلاس Landscaper به جهانیان می گوید را تغییر میدهد. اکنون می گوید: “برای انجام کار من ، شما باید چیزی را در اختیار من قرار دهید که بتواند چمن را قیچی کند cut_grass() . اگر چیزی برای من فراهم کنید که بتواند علف کوتاه کند ، من کار خود را انجام می دهم. برای من مهم نیست که چه چیزی به من می دهی ، فقط به شرطی که بتواند علف ها را کوتاه کند.

خلاصه مثالهای رابط برای PHP شی گرا

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

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

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

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