Här är ett exempel på hur du undviker upprepade if/else. Tycker switch blir lite tydligare i exemplet men den fungerar egentligen som if/else så det är inte direkt någon superfördel.
class ad{
const active = 1;
const paused = 2;
const inactive = 3;
const visitor = 1;
const owner = 2;
const administrator = 3;
public $adState = self::active;
}
class AdWrite{
function displayAd(Ad $ad, $viewmode = ad::visitor)
{
switch($viewmode){
case ad::visitor:
$this->view_visitor_stuff($ad);
break;
case ad::owner;
$this->view_owner_stuff($ad);
break;
case ad::administrator;
$this->view_admin_stuff($ad);
break;
default:
throw new exception("Incorrect viewmode");
break;
}
$this->common_ad_view($ad);
}
function view_administrator_stuff(Ad $ad){
/* Ex. en header med lite länkar till "edit ad", "remove ad", "view users other ads", osv. */
echo $ad->some_adminspecific_options;
}
function view_owner_stuff(Ad $ad){
/* Ex. lite "view other ads I own", "edit this ad", etc. */
echo $ad->owner_stuff;
}
function view_visitor_stuff(Ad $ad){
/* Kanske inte så mycket som en besökare ser som ingen annan ser... */
}
function common_ad_view(Ad $ad){
/* Relevant för alla, ex. hur reklamen ser/såg ut */
echo $ad->stuff_common_for_all_ads;
}
}
Men det verkar ju som att du har massa typiska if/else-grejer så det kan bli svårt att undvika. Du måste förr eller senare handskas med "Om det är en besökare, visa det här. Om det är admin, visa det här!" Om du väljer att göra det med olika funktioner som i mitt exempel, eller i en view-funktion typ:
function view(Ad $ad, $viewmode){
if($viewmode == ad::administrator){
echo "Stäng av användarens reklam";
}elseif($viewmode == ad::owner){
echo "Ta bort reklam";
}elseif($viewmode == ad::visitor){
/* Kommer inte på något exempel */
}
echo $ad->some_ad_property;
}
Är nog lite upp till hur du tycker känns enklast. En stor view-funktion blir snabbt krånglig att underhålla.
Ett annat alternativ är att ex. ge "Ad" en egen "access-mode" och __get funktion, ex:
class ad{
/* Samma consts som ovan */
private $access;
private $adproperties;
function set_access($new_access){
switch($new_access){
case self::administrator:
$this->access = self::administrator;
break;
/* Samma som ovan och exception på default */
}
}
function __get($name){
$owner_properties = array("some_owner_key");
$admin_properties = array("ad_database_id", "other_admin_keys");
if(array_key_exists($name, $this->adproperties){
if(in_array($name, $owner_properties))
{
if($this->access === self::owner || $this->access === self::administrator)
{
return $this->adproperties[$name];
}else{
/* Exception eller false, beroende på hur du väljer att använda funktionen kanske */
throw new exception("Insufficient rights");
}
}
elseif(in_array($name, $admin_properties)){
if($this->access === self::administrator)
{
return $this->adproperties[$name];
}/*Else some ovan */
}
return $this->adproperteis[$name];
}else{
throw new exception("Incorrect name");
}
}
}
Funktionen ovan går bra med en gemensam view_ad funktion i AdWrite för då kan du jämföra med false eller köra try/catch-block så går den igenom allt automatiskt.
Abstraction ftw, fast nu ska jag inte flumma mer!