Trait و Composition
محصول اورجینال INZIP
دانلود پوسته وردپرس باریستا؛ قالب کافیشاپ، رُستری قهوه و فروشگاه قهوه دوزبانه با منوی رومیزی، رزرو آنلاین میز با کد پیامکی و ووکامرس. طراحی اختصاصی inzip.ir
تحویل آنی
آپدیت رایگان
بدون قفل لایسنس
پشتیبانی واقعی
٪۲۶
تخفیف ویژه
۱,۰۳۰,۰۰۰ تومان
Trait ها و Composition در PHP
PHP از وراثت چندگانه کلاسها پشتیبانی نمیکند. برای حل این محدودیت، Trait معرفی شد. همچنین اصل Composition over Inheritance یکی از اصول مهم طراحی شیءگرا است.
Trait چیست؟
Trait مکانیزمی برای استفاده مجدد از کد در کلاسهای مختلف است که با کلمه کلیدی trait تعریف میشود:
<?php
trait SayHello {
public function sayHello(): void {
echo "سلام! من {$this->name} هستم
";
}
public function sayGoodbye(): void {
echo "خداحافظ!
";
}
}
trait HasTimestamps {
private ?DateTime $createdAt = null;
private ?DateTime $updatedAt = null;
public function touch(): void {
$this->updatedAt = new DateTime();
if ($this->createdAt === null) {
$this->createdAt = new DateTime();
}
}
public function getCreatedAt(): ?DateTime {
return $this->createdAt;
}
}
class User {
use SayHello, HasTimestamps;
public function __construct(public string $name) {
$this->touch();
}
}
$user = new User("علی");
$user->sayHello();
echo $user->getCreatedAt()->format('Y-m-d H:i:s');
?>
ترکیب Trait ها
Trait ها میتوانند از یکدیگر استفاده کنند:
<?php
trait LoggerTrait {
public function log(string $message): void {
echo "[" . date('H:i:s') . "] $message
";
}
}
trait EventTrait {
use LoggerTrait;
private array $listeners = [];
public function on(string $event, callable $callback): void {
$this->listeners[$event][] = $callback;
}
public function emit(string $event, mixed $data = null): void {
$this->log("رویداد: $event");
foreach ($this->listeners[$event] ?? [] as $cb) {
$cb($data);
}
}
}
class OrderService {
use EventTrait;
public function placeOrder(): void {
$this->emit('order.placed', ['id' => 123]);
}
}
?>
حل تداخل Trait ها
وقتی دو Trait متد همنام دارند، باید از insteadof و as استفاده کرد:
<?php
trait A {
public function hello() { echo "A"; }
}
trait B {
public function hello() { echo "B"; }
}
class MyClass {
use A, B {
A::hello insteadof B;
B::hello as helloB; // تغییر نام
}
}
$obj = new MyClass();
$obj->hello(); // A
$obj->helloB(); // B
?>
Trait با ویژگیهای Abstract
<?php
trait AbstractMethod {
abstract public function getName(): string;
public function printName(): void {
echo "Name: " . $this->getName();
}
}
class Product {
use AbstractMethod;
public function __construct(private string $name) {}
public function getName(): string {
return $this->name;
}
}
?>
اصل Composition over Inheritance
به جای ارثبری، از ترکیب اشیاء استفاده کنیم:
<?php
// ❌ وراثت - انعطاف کم
class Bird {
public function fly() { /* ... */ }
public function swim() { /* ... */ }
}
class Penguin extends Bird {
// پنگوئن نمیتواند پرواز کند!
// باید متد fly را override کنیم
}
// ✅ Composition - انعطاف بالا
interface FlyBehavior {
public function fly(): void;
}
interface SwimBehavior {
public function swim(): void;
}
class FlyWithWings implements FlyBehavior {
public function fly(): void { echo "پرواز با بال
"; }
}
class FlyNoWay implements FlyBehavior {
public function fly(): void { echo "نمیتواند پرواز کند
"; }
}
class SwimFast implements SwimBehavior {
public function swim(): void { echo "شنای سریع
"; }
}
class Duck {
public function __construct(
private FlyBehavior $flyBehavior,
private SwimBehavior $swimBehavior
) {}
public function performFly(): void {
$this->flyBehavior->fly();
}
public function performSwim(): void {
$this->swimBehavior->swim();
}
public function setFlyBehavior(FlyBehavior $fb): void {
$this->flyBehavior = $fb;
}
}
$duck = new Duck(new FlyWithWings(), new SwimFast());
$duck->performFly(); // پرواز با بال
$duck->setFlyBehavior(new FlyNoWay());
$duck->performFly(); // نمیتواند پرواز کند
?>
Dependency Injection (تزریق وابستگی)
یکی از مهمترین الگوهای Composition:
<?php
interface Mailer {
public function send(string $to, string $subject, string $body): void;
}
class SmtpMailer implements Mailer {
public function send(string $to, string $subject, string $body): void {
// ارسال از طریق SMTP
}
}
class UserService {
public function __construct(private Mailer $mailer) {}
public function register(string $email): void {
// ثبتنام
$this->mailer->send(
$email,
'خوش آمدید',
'ثبتنام شما با موفقیت انجام شد'
);
}
}
// استفاده
$service = new UserService(new SmtpMailer());
$service->register("user@example.com");
?>
Service Container (مفهوم)
<?php
class Container {
private array $bindings = [];
public function bind(string $abstract, callable $concrete): void {
$this->bindings[$abstract] = $concrete;
}
public function make(string $abstract): mixed {
if (!isset($this->bindings[$abstract])) {
throw new Exception("سرویس $abstract ثبت نشده");
}
return call_user_func($this->bindings[$abstract], $this);
}
}
$container = new Container();
$container->bind(Mailer::class, fn() => new SmtpMailer());
$container->bind(UserService::class, fn($c) => new UserService($c->make(Mailer::class)));
$service = $container->make(UserService::class);
?>
مقایسه نهایی
معیار Inheritance Composition
انعطافپذیری کم بالا
پیچیدگی افزایش با عمق خطی
تستپذیری سختتر آسانتر
استفاده مجدد سلسلهمراتبی آزادانه
زمان مناسب رابطه "is-a" رابطه "has-a"
نتیجهگیری
Trait ها ابزار خوبی برای استفاده مجدد از کد هستند اما نباید جایگزین طراحی خوب شوند. اصل Composition over Inheritance یکی از مهمترین اصول SOLID است که در پروژههای بزرگ حتماً باید رعایت شود.
٪۴۱
دوره اختصاصی INZIP
آموزش حرفه ای HTML از صفر در ۱۶ ویدیو: سند، متن، لینک، تصویر، جدول، فرم، معناییسازی، دسترسپذیری و سئو، تا پروژهٔ کامل صفحهٔ فروشگاه محصول.
تماشای آنلاین + دانلود
دسترسی آنی و همیشگی
بهروزرسانی رایگان
کیفیت Full HD
۹۹۰,۰۰۰ تومان
۵۹۰,۰۰۰ تومان
سود شما ۴۰۰,۰۰۰ تومان
مشاهده سریال