//usage of command pattern to refactoring big or overloaded methods
//Gigantic classes with hard to change methods
class Wrong_Customer {
var $_age;
var $_bill;
var $_man;
function __construct($age, $bill, $man) {
$this->_age=$age;
$this->_bill=$bill;
$this->_man= $man;
}
//addind discount will require modyfy other classes
//new calculation devices requre to chenge methods
function returnFinalBill() {
$discountPercent=0;
if($this->_age >60) { $discountPercent +=0.10;}
if(!$this->_man) { $discountPercent +=0.20;}
$bill = $this->_bill*(1-$discountPercent); //100%=1
return ("Wrong Customer Bill Amount: $".$bill."
");
}
}
interface BillPlayer {
//based on sex how to calculate bill
public function calculateBill($amountDue);
}
interface Command {
//methods that change
function executeCalculateBill($amountDue);
}
class WomanOver60 implements BillPlayer {
public function calculateBill($amountDue) {
return "Bill Amount for Woman over 60: $".($amountDue*(1-0.30))."
";
}
}
class ManOver60 implements BillPLayer {
public function calculateBill($amountDue) {
return "Bill Amount for Man over 60: $".($amountDue*(1-0.10))."
";
}
}
class ManUnder60 implements BillPLayer {
public function calculateBill($amountDue) {
return "Bill Amount for Man under 60: $".($amountDue)."
"; //no discount
}
}
class Waiter implements Command { //Comander
var $_billPayer;
function __construct(BillPlayer $billPayer) {
$this->_billPayer=$billPayer;
}
function executeCalculateBill($amountDue) {
return $this->_billPayer->calculateBill($amountDue);
}
}
class CashRegister { //invoker from command pattern, execute diferent methods based onobject type passed
//return final bill
//_Waiter diferent weiters, !adds flexibility!
//stores Command's
var $_command;
function __construct(Command $command) {
$this->_command=$command; //all things that implements command //like waiters
}
function returnFinalBill($amountDue) {
return $this->_command->executeCalculateBill($amountDue);
}
}
// more flexebility - only one thing to change for adding bill Payers
class CustomerTypePicker { //if u want NEW bill payer tpe goes here!!!
static function getManOver60(){
return new ManOver60();
}
static function getManUnder60(){
return new ManUnder60();
}
static function getWomanOver60(){
return new WomanOver60();
}
}
//adding customer group for easier to menage diferent customers
class CustomerGroup {
private $_customers=array();
function __construct($customers=array()) {
$this->_customers = $customers;
}
function getCustomer($index) {
return $this->_customers[$index];
}
function addCustomer(BillPlayer $customer) {
return $this->_customers[]=$customer;
}//TODO deleteCustomer
}
class Main {
function __construct() {
$wC = new Wrong_Customer(70, 100, false); //woman Over 60
echo $wC->returnFinalBill();
}
function testCommandOnWomenOver60() {
$picker = new CustomerTypePicker();
$sally = $picker::getWomanOver60();
$waiter = new Waiter($sally); //sallysWaiter
$bill = new CashRegister($waiter);
echo $bill->returnFinalBill(100);
}
function testCommandOnManOver60() { //NOW better groups customers to array
$picker = new CustomerTypePicker();
$bob = $picker::getManOver60();
$waiter = new Waiter($bob); //sallysWaiter
$bill = new CashRegister($waiter);
echo $bill->returnFinalBill(100);
}
function testCustomerGroup() {
$picker = new CustomerTypePicker();
$customerGroup = new CustomerGroup();
$sally = $picker::getWomanOver60();
$customerGroup->addCustomer($sally);
echo $customerGroup->getCustomer(0)->calculateBill(100);
}
}
$run = new Main();
$run->testCommandOnWomenOver60();
$run->testCommandOnManOver60();
$run->testCustomerGroup();
Java implementation here:
http://www.newthinktank.com/2013/02/code-refactoring-13/
wtorek, 12 lutego 2013
Refactoring To Command Pattern
Subskrybuj:
Komentarze do posta (Atom)
Brak komentarzy:
Prześlij komentarz