我开始编写我的项目代码,在过去未完成的项目中,我使用了两种不同的模式来管理需要管理以下内容的用户类的设计:
尽管如此,我们还要考虑这个用户类将由会话类扩展,该会话类只将焦点用户ID设置为查看页面的用户提供的id。
我们还将使用此类users
来管理用户组。
我使用的2个选项如下(简化):
用于不同目的的不同课程
- class UserMaker($username, $password, $email);
function giveBirth(); // create the user
- class UserManager($id);
function edit($field, $value); // edit a specific user field
function save(); // save all the edits with a single query
function setTrusted(); // set that user as trusted
function setAdmin(); // set that user as admin
function setBanned(); // ban the specific user
- class UserReader($id);
function get($field); // Get the value of a single field
function getAll(); // Get all fields from that user as associative array
function isAdmin(); // self explanation
function isRegistered(); // self explanation
function isBanned(); // self explanation
单班
- class User($id);
function static giveBirth($username, $password, $email); // create the user, notice this is static
function edit($field, $value); // edit a specific user field
function save(); // save all the edits with a single query
function setTrusted(); // set that user as trusted
function setAdmin(); // set that user as admin
function setBanned(); // ban the specific user
function get($field); // Get the value of a single field
function getAll(); // Get all fields from that user as associative array
function isAdmin(); // self explanation
function isRegistered(); // self explanation
function isBanned(); // self explanation
基本上,由于唯一不接受$ id作为__construct()
参数的类是UserMaker,我们只需将函数giveBirth()
设置为静态,这样我们就可以创建用户了。
设计此模式的最佳方法是什么?你有第三种选择,你感觉比这些更好吗?
答案 0 :(得分:6)
嗯,这个问题的答案特别与{{3}}有关。基本上,您的应用程序中的每个类应该只有一个责任。这并不意味着它不能在多种情况下使用,但对于多个抽象概念,它不应该负责。
因此,从您的示例中,我将构建一个类似于此的类结构:
class UserFactory()
getModel();
getUser($id, $model = null);
getACL($user);
class UserModel ()
edit($id = 0);
load($id = 0);
reload($id = 0);
save($id = 0);
class User ($data)
getAll();
getField($field);
class UserACL (User $user)
isTrustedUser();
isAdminUser();
isBannedUser();
这样,一切都是由责任和角色组织的,而不是由关系组织的。这样做的好处是,如果您想稍后换出单个组件(例如,ACL系统或模型存储层),则无需担心测试大型类。只需测试该特定API即可。
答案 1 :(得分:0)
我不知道你究竟是如何在你的系统中组织/构思的,尽管从我使用的方法来看,我发现最有效的处理方法是将对象视为服务,例如: 你的软件中会有多少次调用giveBirth方法?一次,两次以上?为什么更多?
虽然假设您的用户对象必须公开每次都无法在确切位置调用的方法,或者您希望它具有更普遍的效果。
在单例中,您将拥有一个init静态方法,该方法可以接收id以创建用户实例。你会在索引中有这样的东西,因为我认为你的应用程序只有一个条目
UserSingleton::init($_SESSION["id"]);
请求进程初始化用户对象后,您可以使用它:
$user = UserSingleton::getInstance(); // will return the instance of singleton
$user->setBanned();// or whatever you need to call;
观测值: 你可以通过像这样创建getInstanceMethod来避免使用init方法:
public function getInstance(){
if(!isset(self::$instance) {
self::$instance = new UserSingleton($_SESSION["user_id"]) ;
}
return self::$instance;
}
请注意,这不能处理与数据库交互等内容,这应该通过外部资源接收/发送数据到数据库。它是一个帮助者,而不是一个商业模型/对象。这是另一个问题。