컴포지션과 상속 비교
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 56번째.
이전 장에서는 트레이트가 "has-a" 기능을 제공하는 반면 상속은 "is-a" 관계를 설정한다는 것을 배웠습니다. 구성은 더 단순한 객체로 복잡한 객체를 만들고, 이를 상속하는 대신 properties로 저장함으로써 "has-a" 개념을 한 단계 더 발전시킵니다.
상속을 사용하면 Car가 Vehicle을 확장할 수 있습니다. 컴포지션을 사용하면 Car는 Engine 객체를 포함합니다:
<?php
class Engine {
public function start(): string {
return "Engine started";
}
}
class Car {
private Engine $engine;
public function __construct() {
$this->engine = new Engine();
}
public function start(): string {
return $this->engine->start();
}
}
$car = new Car();
echo $car->start();
출력:
Engine startedCar class는 Engine을 상속하지 않습니다. 대신 하나를 소유합니다. 이 접근 방식은 상당한 장점을 제공합니다. engine을 다른 구현으로 교체할 수 있고, class 간 결합도가 낮게 유지되며, 깊은 상속이 만들어 내는 경직된 계층 구조를 피할 수 있습니다.
OOP에서 흔히 따르는 지침은 "상속보다 구성을 선호하라."입니다. 상속은 진정한 타입 계층 구조(Dog가 실제로 Animal인 경우)에 잘 맞지만, 독립적인 부분으로 기능을 조합할 때는 구성이 빛을 발합니다. 여러 objects를 결합하고, 런타임에 이를 교체하며, 구성 요소를 독립적으로 테스트할 수 있습니다.
다음 레슨에서는 객체가 의존성을 받는 방식을 제어하여 컴포지션을 직접 기반으로 구축하는 의존성 주입을 살펴봅니다.
챌린지
쉬움상속하는 대신 별도의 component objects로부터 Computer를 조립하는 composition을 사용하여 computer system을 만들어 보겠습니다. 이를 통해 composition이 더 단순하고 독립적인 부분으로부터 복잡한 objects를 구축할 수 있게 하는 방식을 확인할 수 있습니다.
코드를 세 개의 파일로 구성합니다:
Processor.php: CPU를 나타내는Processorclass를 Create합니다. constructor promotion을 사용하여 private$model(string)과 private$cores(integer)를 define합니다.getSpecs()method를 추가하고"[model] ([cores] cores)"를 반환하도록 합니다.Memory.php: RAM을 나타내는Memoryclass를 Create합니다. constructor promotion을 사용하여 GB를 나타내는 private$size(integer)를 define합니다.getCapacity()method를 추가하고"[size]GB RAM"을 반환하도록 합니다.main.php: 두 component 파일을 모두 포함하고 composition을 사용하는Computerclass를 Create합니다.Computer는 다음을 수행해야 합니다:Processorobject와Memoryobject를 private properties로 저장- constructor에서 processor model, core 개수, memory size를 accept
- constructor 실행 중 component objects를 internally Create
"Computer with [processor specs] and [memory capacity]"를 반환하는describe()method를 가짐
세 가지 입력을 받습니다. processor model, cores의 개수, GB 단위의 memory size입니다. 이러한 사양으로
Computer를 Create하고describe()를 호출한 result를 print합니다.
Computer가 Processor나 Memory를 extend하지 않는다는 점에 주목하세요. Computer는 이들을 포함합니다. composition을 통한 이러한 "has-a" 관계는 각 component를 독립적이고 재사용 가능하게 유지하면서, 필요할 때 Computer가 해당 부분에 작업을 Delegate할 수 있도록 합니다.
직접 해보기
<?php
require_once 'Processor.php';
require_once 'Memory.php';
class Computer
{
// TODO: Processor와 Memory 객체를 저장할 private 프로퍼티를 정의하세요
// TODO: 생성자는 프로세서 모델, 코어 수, 메모리 크기를 받아야 합니다
// 그리고 내부적으로 컴포넌트 객체를 생성해야 합니다
public function __construct()
{
// TODO: Processor와 Memory 객체를 생성하고 저장하세요
}
// TODO: 다음을 반환하는 describe() 메서드를 구현하세요
// "Computer with [processor specs] and [memory capacity]"
public function describe(): string
{
// TODO: 컴포넌트 객체에 위임하고 형식화된 문자열을 반환하세요
}
}
// 입력 읽기
$processorModel = trim(fgets(STDIN));
$cores = intval(fgets(STDIN));
$memorySize = intval(fgets(STDIN));
// TODO: 주어진 사양으로 Computer를 생성하고 describe()의 결과를 출력하세요
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러