组合和接口/依赖注入怎么样?
<?php
interface IPlayer {
public function __toString();
}
class Player implements IPlayer {
protected $_id;
protected $_name;
public function __construct( $id, $name ) {
$this->_id = $id;
$this->_name = $name;
}
public function getId() { return $this->_id; }
public function setId($id) { $this->_id = $id; }
public function setName($n) { $this->_name = $n; }
public function getName() { return $this->_name; }
public function __toString() {
return 'my name is ' . $this->_name . ' and my id is ' . $this->_id;
}
}
class ComposedPlayer implements IPlayer {
protected $_player;
public function __construct( IPlayer $p ) {
$this->_player = $p;
}
public function __set($k, $v) {
$this->_player->$k = $v;
}
public function __get($k) {
return $this->_player->$k;
}
public function __call($func, $args) {
return call_user_func_array( array( $this->_player, $func ), $args );
}
public function __toString() {
return $this->_player->__toString();
}
}
class AttackPlayer extends ComposedPlayer {
function getNameMod() {
return 'attack player ' . $this->getName();
}
public function __toString() {
return parent::__toString() . ' and im an attack player';
}
}
class ProtectedPlayer extends ComposedPlayer {
function getNameMod() {
return 'protected player ' . $this->getName();
}
public function __toString() {
return parent::__toString() . ' and im an protected player';
}
}
class TeamPlayer extends ComposedPlayer {
function getIdMod() {
return $this->getId() - 10;
}
public function __toString() {
return parent::__toString() . ' and im an team player';
}
}
class FreePlayer extends ComposedPlayer {
function getIdMod() {
return $this->getId() + 10;
}
public function __toString() {
return parent::__toString() . ' and im an free player';
}
}
$free_attack_player = new FreePlayer( new AttackPlayer( new Player( 100, 'John' ) ) );
$free_protected_player = new FreePlayer( new ProtectedPlayer( new Player( 101, 'Bob' ) ) );
$team_attack_player = new TeamPlayer( new AttackPlayer( new Player( 102, 'Bill' ) ) );
$team_protected_player = new TeamPlayer( new ProtectedPlayer( new Player( 104, 'Jim' ) ) );
foreach ( array( $free_attack_player, $free_protected_player, $team_attack_player, $team_protected_player ) as $p ) {
echo 'id: ', $p->getId(), ' name: ', $p->getName(), ' mod id: ', $p->getIdMod(), ' mod name: ', $p->getNameMod(), PHP_EOL;
}
foreach ( array( $free_attack_player, $free_protected_player, $team_attack_player, $team_protected_player ) as $p ) {
echo $p, PHP_EOL;
}
执行此操作将产生:
id: 100 name: John mod id: 110 mod name: attack player John
id: 101 name: Bob mod id: 111 mod name: protected player Bob
id: 102 name: Bill mod id: 92 mod name: attack player Bill
id: 104 name: Jim mod id: 94 mod name: protected player Jim
my name is John and my id is 100 and im an attack player and im an free player
my name is Bob and my id is 101 and im an protected player and im an free player
my name is Bill and my id is 102 and im an attack player and im an team player
my name is Jim and my id is 104 and im an protected player and im an team player
编辑:更新以向接口添加 __toString(),这是方法组合的简单示例。