我正在尝试用PHP创建一个简单的工厂模式演示。我不确定我的代码是否是最佳实践。似乎我有一些重复的代码,但我不确定如何改进它。基本上,我想创建3种类型的帐户(基本,高级和贵宾)。请给我建议。非常感谢。
抽象类
abstract class User {
function __construct() {
$this->db= new Database('mysql','localhost','mvcdb','root','');
}
abstract function checkUser();
function showAccountCredit(){
return $this->credits;
}
function getUserName(){
return $this->username;
}
}我有3种不同的用户帐户类型:
基本帐号
class BasicUser extends User {
function __construct($username) {
parent::__construct();
$this->username=$username;
$this->credit='10';
$this->accountType='Basic Account';
$data=$this->checkUser();
if(!empty($data)){
echo 'The username: '.$this->username.' already exists<br>';
return false;
}
$array=array('username'=>$this->username, 'password'=>'password','credit'=> $this->credit,'accountType'=>$this->accountType);
$this->db->insert('user',$array);
}
function checkUser(){
$array=array(':username'=>$this->username);
$results=$this->db->select('SELECT * FROM USER WHERE username=:username',$array);
if(!empty($results)){
$this->credit=$results[0]['credit'];
$this->accountType=$results[0]['accountType'];
}
return $results;
}
function showAccountCredit() {
echo 'Username: '.$this->username.'<br>';
echo 'Account Credit: '.$this->credit.'<br>';
echo 'Account Type: '.$this->accountType;
}
}高级帐户
class PremiumUser extends User {
function __construct($username) {
parent::__construct();
$this->username=$username;
$this->credit='100';
$this->accountType='Premium Account';
$data=$this->checkUser();
if(!empty($data)){
echo 'The username: '.$this->username.' already exists<br>';
return false;
}
$array=array('username'=>$this->username, 'password'=>'password','credit'=> $this- >credit,'accountType'=>$this->accountType);
$this->db->insert('user',$array);
}
function checkUser(){
$array=array(':username'=>$this->username);
$results=$this->db->select('SELECT * FROM USER WHERE username=:username',$array);
if(!empty($results)){
$this->credit=$results[0]['credit'];
$this->accountType=$results[0]['accountType'];
}
return $results;
}
function showAccountCredit() {
echo 'Username: '.$this->username.'<br>';
echo 'Account Credit: '.$this->credit.'<br>';
echo 'Account Type: '.$this->accountType.'<br>';
}
}VIP帐号:
class VipUser extends User {
function __construct($username) {
parent::__construct();
$this->username=$username;
$this->credit='1000';
$this->accountType='VIP Account';
$data=$this->checkUser();
if(!empty($data)){
echo 'The username: '.$this->username.' already exists<br>';
return false;
}
$array=array('username'=>$this->username, 'password'=>'password','credit'=> $this->credit,'accountType'=>$this->accountType);
$this->db->insert('user',$array);
}
function checkUser(){
$array=array(':username'=>$this->username);
$results=$this->db->select('SELECT * FROM USER WHERE username=:username',$array);
if(!empty($results)){
$this->credit=$results[0]['credit'];
$this->accountType=$results[0]['accountType'];
}
return $results;
}
function showAccountCredit() {
echo 'Username: '.$this->username.'<br>';
echo 'Account Credit: '.$this->credit.'<br>';
echo 'Account Type: '.$this->accountType;
}
}UserFactory类
class UserFactory {
static function create($username,$accountType){
$accountType = strtolower($accountType);
switch($accountType){
case 'basic': return new BasicUser($username);
case 'premium':return new PremiumUser($username);
case 'vip': return new VipUser($username);
default :return new BasicUser($username);
}
}index.php
$user1= UserFactory::create('Jerry', 'Vip');
$user1->showAccountCredit();
$user2= UserFactory::create('Bob', 'Basic');
$user2->showAccountCredit();
$user3= UserFactory::create('Betty', 'premium');
$user3->showAccountCredit();发布于 2012-05-17 05:54:26
考虑"UserType“的3个不同实现,而不是3个不同的user实现。分离职责并将对象组合在一起。这是另一种运行中的模式,称为策略。
function showAccountCredit(){
return $this->type->showAccountCredit();
}新的类,UserType代表特殊的行为,然后用户将包含其余的泛型内容,减少您描述的重复(或至少大部分)
另一方面,工厂可以用于从db加载对象:
class Loader{
private $userTypeFactory;
public function loadUser($id){
$userRow = $db->loadRow();
...
$userType = $userTypeFactory->$userRow["type"]();
return new User($userType);
}
}
class UserTypeFactory{
public function vip(){
return new VipUserType();
}
public function premium(){
return new PremiumUser();
}
}您可以更进一步,引入IoC框架。在symfony2上看看吧。哦,请不要使用switch,而是像我一样做,多态,动态调用。
编辑:
策略==包装行为。例如,如果您正在检查查看付费内容的用户权限,则通常如下所示:
class PagesController{
...
public function showPage($id){
...
if ($user->type == "premium" || $user->type == "vip"){
...
}
else if ($user->type == "credit"){
$user->credits--;
updateUser();
}
else{
die("You do not have permissions to see this content...");
}
... //render page
}
}下面是使用“策略”时的样子:
class PagesController{
...
public function showPage($id){
$page = ...;
$user->pageRequested($page);
//render page
}
}
class User{
private $userType;
public function pageRequested($page){
$this->userType->userRequestedPage($user, $page);
}
}
class VipUserType{
public function userRequestedPage($user, $page){
//do nothing
}
}
class PremiumUserType{
public function userRequestedPage($user, $page){
//do nothing
}
}
class BasicUserType{
public function userRequestedPage($user, $page){
throw new Exception("You cant access this page");
}
}
class CreditUserType{
public function userRequestedPage($user, $page){
$user->credit--;
$user->save();
}
}这样,所有与userType相关的东西都被分离了,很容易添加新的类型,而不会有破坏现有类型的风险。
顺便说一句:这只不过是简单的多态。策略只是OOP本质的另一个闪亮的词,就像大多数模式一样。不要浪费时间去思考模式,它们对灵感很有帮助,但是你会从真正的OOP中获得更多的经验,看看smalltalk - http://www.pharo-project.org/home
https://stackoverflow.com/questions/10626215
复制相似问题