PHP로 Design Patterns 예제 - Strategy / Observer / Command 패턴을 섞다.

PHP로 Design Patterns 예제 - Strategy / Observer / Command 패턴을 섞다.

<?php
// http://www.ibm.com/developerworks/library/os-php-designptrns/
////////////////////////////////////////////////
////////////////////////////////////////////////

interface IStrategy
{
  function
filter( $record );
}

class FindAfterStrategy implements IStrategy
{
  private
$_name;

  public function __construct( $name )
  {
   
$this->_name = $name;
  }

  public function filter( $record )
  {
    return
strcmp( $this->_name, $record ) <= 0;
  }
}

class RandomStrategy implements IStrategy
{
  public function
filter( $record )
  {
    return
rand( 0, 1 ) >= 0.5;
  }
}

////////////////////////////////////////////////
////////////////////////////////////////////////

interface IObserver
{
  function
onAdded( $sender, $args );
  function
onDeleted( $sender, $args );
}

interface IObservable
{
  function
addObserver( $observer );
}

////////////////////////////////////////////////
////////////////////////////////////////////////

interface ICommand
{
  function
onCommand( $name, $args );
}

class CommandChain
{
  private
$_commands = array();

  public function addCommand( $cmd )
  {
   
$this->_commands []= $cmd;
  }

  public function runCommand( $name, $args )
  {
    foreach(
$this->_commands as $cmd )
    {
      if (
$cmd->onCommand( $name, $args ) )
        return;
    }
  }
}

////////////////////////////////////////////////
////////////////////////////////////////////////

class UserList implements IObservable
{
    private
$_list = array();
    private
$_observers = array();

    public function addObserver( $observer )
    {
       
$this->_observers []= $observer;
    }

    public function __construct( $names )
    {
        if (
$names != null )
        {
            foreach(
$names as $name )
            {
               
$this->_list []= $name;
            }
        }
    }

    public function add( $name )
    {
       
$this->_list []= $name;
        foreach(
$this->_observers as $obs )      $obs->onAdded( $this, $name );
    }

    public function del( $name )
    {
       
deleteFromArray( $this->_list, $name, false );
        foreach(
$this->_observers as $obs )      $obs->onDeleted( $this, $name );
    }

    public function find( $filter )
    {
       
$recs = array();
        foreach(
$this->_list as $user )
        {
            if (
$filter->filter( $user ) )        $recs []= $user;
        }
        return
$recs;
    }
}

class UserListObserver implements IObserver
{
    private
$command;

    public function __construct()   
    {
       
$this->command = new CommandChain();
       
$this->command->addCommand( new UserListCommand() );
    }

    public function onAdded( $sender, $args )
    {
        echo(
"'$args' added user list\n<br>" );
       
$this->command->runCommand( 'add', $args );
    }

    public function onDeleted( $sender, $args )
    {
        echo(
"'$args' deleted from user list\n<br>" );
       
$this->command->runCommand( 'del', $args );
    }
}

class UserListCommand implements ICommand
{
    public function
onCommand( $name, $args )
    {
        
$arrValidCommand = array( 'add', 'del' );

        if ( !in_array( $name, $arrValidCommand ) )    return false;

        if ( $name == 'add' )    echo( "Say to all users : added $args \n<br />" );
        if (
$name == 'del' )    echo( "Say to all users : deleted $args \n<br />" );
        return
true;
    }
}

$ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) );
$ul->addObserver( new UserListObserver() );

$f1 = $ul->find( new FindAfterStrategy( "J" ) );
echo
"<pre>".print_r( $f1, true )."</pre>";

$ul->add( "Lori2" );
$f2 = $ul->find( new FindAfterStrategy( "J" ) );
echo
"<pre>".print_r( $f2, true )."</pre>";

$ul->del( "Lori" );
$f3 = $ul->find( new FindAfterStrategy( "J" ) );
echo
"<pre>".print_r( $f3, true )."</pre>";

// $f2 = $ul->find( new RandomStrategy() );
// echo "<pre>".print_r( $f2, true )."</pre>";

/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////

/*
* This function deletes the given element from a one-dimension array
* Parameters: $array:    the array (in/out)
*             $deleteIt: the value which we would like to delete
*             $useOldKeys: if it is false then the function will re-index the array (from 0, 1, ...)
*                          if it is true: the function will keep the old keys
* Returns true, if this value was in the array, otherwise false (in this case the array is same as before)
*/
function deleteFromArray(&$array, $deleteIt, $useOldKeys = FALSE)
{
   
$tmpArray = array();
   
$found = FALSE;
    foreach(
$array as $key => $value)
    {
        if(
$value !== $deleteIt)
        {
            if(
FALSE === $useOldKeys)
            {
               
$tmpArray[] = $value;
            }
            else
            {
               
$tmpArray[$key] = $value;
            }
        }
        else
        {
           
$found = TRUE;
        }
    }
 
   
$array = $tmpArray;
 
    return
$found;
}
?>

PHP5 이상에서의 실행결과는 다음과 같다.

Array
(
    [0] => Jack
    [1] => Lori
    [2] => Megan
)

'Lori2' added user list
Say to all users : added Lori2

Array
(
    [0] => Jack
    [1] => Lori
    [2] => Megan
    [3] => Lori2
)

'Lori' deleted from user list
Say to all users : deleted Lori

Array
(
    [0] => Jack
    [1] => Megan
    [2] => Lori2
)

댓글 쓰기

CAPTCHA
스팸방지를 위해 아래에 보이는 영문/숫자를 입력해 주세요.
Image CAPTCHA
Enter the characters shown in the image.