여러 트레이트 사용하기
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 52번째.
단일 트레이트(trait)도 유용하지만, 진정한 힘은 하나의 클래스에 여러 트레이트를 결합할 때 나타납니다. PHP를 사용하면 필요한 만큼 많은 트레이트를 포함할 수 있으며, 이를 통해 클래스에 여러 소스의 기능을 동시에 부여할 수 있습니다.
여러 개의 트레이트(trait)를 사용하려면, use 키워드 뒤에 쉼표로 구분하여 나열하면 됩니다:
<?php
trait Timestampable {
public function getTimestamp(): string {
return date('Y-m-d H:i:s');
}
}
trait Identifiable {
private string $id;
public function generateId(): void {
$this->id = uniqid('id_');
}
public function getId(): string {
return $this->id;
}
}
class Post {
use Timestampable, Identifiable;
public function __construct(public string $title) {
$this->generateId();
}
}
$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();
출력:
id_6789abc123 - 2024-01-15 10:30:00Post 클래스는 이제 두 트레이트의 메서드를 모두 가집니다. 각 트레이트는 고유한 기능을 제공합니다 - Timestampable은 시간 관련 메서드를 제공하고, Identifiable은 고유 ID를 처리합니다. 이 방식은 각 트레이트가 단일 책임에 집중하도록 유지하여 코드를 더 모듈화하고 재사용 가능하게 만듭니다.
두 개의 트레이트(trait)가 같은 이름의 메서드(method)를 가지고 있으면 어떻게 될까요? 이는 다음 레슨에서 살펴볼 충돌 상황입니다.
챌린지
쉬움여러 개의 trait를 결합하여 제품에 가격 책정 및 재고 관리 기능을 모두 부여하는 제품 관리 시스템을 구축해 보겠습니다. 각 trait는 단일 책임을 처리하며, 제품 클래스는 두 trait로부터 기능을 얻게 됩니다.
코드는 다음 세 개의 파일로 구성됩니다:
Priceable.php— 가격 책정 기능을 처리하는Priceable이라는 trait를 생성합니다. 이 trait는 다음을 포함해야 합니다:- private 속성
$price(float) - 가격을 저장하는
setPrice(float $price)메서드 - 가격을 반환하는
getPrice()메서드 - 가격을 소수점 2자리까지 포함된
"$[price]"형식으로 반환하는getFormattedPrice()메서드
- private 속성
Stockable.php— 재고를 관리하는Stockable이라는 trait를 생성합니다. 이 trait는 다음을 포함해야 합니다:- private 속성
$stock(integer) - 재고 수량을 저장하는
setStock(int $quantity)메서드 - 현재 재고를 반환하는
getStock()메서드 - 재고가 0보다 크면
true를, 그렇지 않으면false를 반환하는isInStock()메서드
- private 속성
main.php— 두 trait 파일을 포함하고Priceable과Stockabletrait를 모두 사용하는Product클래스를 생성합니다. 생성자 프로모션(constructor promotion)을 사용하여 public$name속성을 정의하세요. 생성자는 가격과 재고 수량도 인자로 받아야 하며, trait 메서드를 사용하여 이를 설정해야 합니다.제품 이름, 가격, 재고 수량이라는 세 가지 입력을 받게 됩니다. 이 값들로 제품을 생성하고 다음 네 줄을 출력하세요:
- 제품 이름
- 형식화된 가격 (
getFormattedPrice()사용) - 재고 수량
- 재고가 있는 경우
"Available", 없는 경우"Out of stock"
이것은 여러 trait가 어떻게 함께 작동하는지 보여줍니다. Product 클래스는 한 trait에서 가격 책정 기능을, 다른 trait에서 재고 관리 기능을 얻어 각 관심사를 깔끔하게 분리하면서도 모든 기능을 갖춘 제품으로 결합합니다.
치트 시트
클래스에서 여러 개의 트레이트(trait)를 사용하려면, use 키워드 뒤에 쉼표로 구분하여 나열합니다:
<?php
trait Timestampable {
public function getTimestamp(): string {
return date('Y-m-d H:i:s');
}
}
trait Identifiable {
private string $id;
public function generateId(): void {
$this->id = uniqid('id_');
}
public function getId(): string {
return $this->id;
}
}
class Post {
use Timestampable, Identifiable;
public function __construct(public string $title) {
$this->generateId();
}
}
$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();
// 출력: id_6789abc123 - 2024-01-15 10:30:00
각 트레이트는 클래스에 고유한 기능을 제공합니다. 이러한 방식은 각 트레이트가 단일 책임에 집중하도록 유지하여, 코드를 더욱 모듈화하고 재사용 가능하게 만듭니다.
직접 해보기
<?php
require_once 'Priceable.php';
require_once 'Stockable.php';
// TODO: Priceable 및 Stockable 트레이트를 모두 사용하는 Product 클래스를 생성하세요.
// public $name 속성에 대해 생성자 프로모션(constructor promotion)을 사용하세요.
// 생성자는 name, price, stock을 인자로 받아야 하며, 트레이트 메서드를 사용하여 price와 stock을 설정해야 합니다.
class Product {
// TODO: 여기서 트레이트를 사용하세요.
// TODO: $name에 대한 생성자 프로모션을 포함한 생성자를 구현하고,
// 트레이트 메서드를 사용하여 price와 stock을 설정하세요.
}
// 입력 읽기
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$stock = intval(trim(fgets(STDIN)));
// TODO: 입력된 값으로 Product 인스턴스를 생성하세요.
// TODO: 제품 이름을 출력하세요.
// TODO: getFormattedPrice()를 사용하여 형식화된 가격을 출력하세요.
// TODO: 재고 수량을 출력하세요.
// TODO: 재고가 있으면 "Available"을, 없으면 "Out of stock"을 출력하세요.
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8매직 메서드
매직 메서드 소개__toString 및 __debugInfo__get, __set, __isset, __unset__call 및 __callStatic__clone 및 객체 복제__serialize 및 __unserialize요약 - 커스텀 컬렉션