【发布时间】:2018-03-03 17:29:24
【问题描述】:
进一步研究 OOP 和类,我有一个非常大的用户类,它的管理规模越来越大。总代码超过 950 行,完全摒弃了单一职责原则。
我认为缩小它的几种方法是创建完全独立的类并将数据传输到新类的构造中。例如:
index.php
$user = new user('username');
$userOptions = new userOptions($user);
或
$user = new user;
$userOptions = new userOptions;
$userOptions->setData(
$user->getData([
'username'=>'genericuser'
]),
);
然而,这似乎不自然,也没有我期望的格式正确的代码那么好。
我想到的另一种方法是将基类扩展到另一个基类。例如:
index.php
$userOptions = new userOptions('username');
classes/useroptions.php
class userOptions extends User {
//a small section of what would be a big user class
}
但这也违反了一些 PHP 实践,extends 通常表示 一种特殊情况,而用户选项似乎不是。
我组织文档的最后一种方式是在默认类中使用将大文件分开,例如:
classes/user.php
class User {
/**
* CREATION SECTION
*/
public function create() {
//create user
}
/**
* UPDATE SECTION
*/
public function change($whattochange) {
//what to change
}
}
然而,这似乎再次违反了单一职责原则,许多选项都在一个类中。
什么是划分类的常见做法,应该怎么做?
当前的 User 类内部有以下方法:
* - $variables
* - __construct gets a new user.
* - stripeCustomer() gets the customer information if it exists
* - create($fields|array) method to create a new user
* - login($username|string, $password|string, $remember|bool) logs in a user
* - find ($param|string, $method|string) finds a user WHERE param=method
* - data() returns user data
* - isLoggedIn() returns whether a user is logged in
* - isAdmin() returns if a user is an admin
* - logout() logs out current user
* - displayName() returns first name or username
* - isVerified() checks if a user is verified
* - inCompany() checks if a user is in a company
* - inVerifiedCompany() checks if a user id in a verified company
* - verifyUser($apicode|string, $verification|string, $resend|bool) verifies a users email
* - error() returns any errors that may occur
* - getProfilePicture($size|int) gets a users profile picture from Gravatar with size of $size in pixels
* - passwordCheck($password|string) checks if two passwords match
*
* // 2FA section
* - has2FA() checks if the user has 2FA enabled
* - TOTP($type|string, $secret|string, $code|string, $backupcodes|array) everything to do with 2FA
* - countBackups() counts the amount of backup codes remaining for a user with 2FA
* - update($statement|string, $params|array, $apicode|string) updates a user
*
* // lockdown system
* - getAttempts() gets amount of attempts to break into a users account
* - isLocked() gets whether the user account is locked
* - addAttempt() adds an attempt to a users account
* - reinstateUser() unlocks a users account
* - shouldShowCaptcha() checks whether a captcha is needed
*
* // codes
* - sendRequest($code|int) sends a request to a users email with a specific code
* - verifyCode($code|string, $type|int) checks a user inputted code to one in the DB
*
* - deleteUser() deletes the specific user
* - makeAdmin() makes the user an admin
* - removeAdmin() removes the user as an admin
* - modify($changes|array, $apicode|string) modifies a user | no idea how this is different to update
我也明白该类的数据库部分应该在一个单独的映射器类中,它将使用与我最初尝试相同的样式结构,这将很快改变。
提前感谢所有帮助。
作为参考,我查看了谷歌,发现有些人提出了类似的问题,但似乎没有人在很大程度上回答了这个问题。 How to break up a large class
【问题讨论】:
-
我喜欢你如何标记这个问题
object-oriented-analysis,因为这就是这个问题的意义所在。班级的大小无关紧要;如果你的分析告诉你类需要来做所有这些事情,那么它的大小也是如此。然而,在这种情况下,User类的责任太多了:它拥有关于自身的知识,但也管理着安全性。您有权承认违反 SRP 规则。您需要做的就是改进您的分析并调整您的实现以匹配设计。将User类剥离到最低限度,然后从那里开始。
标签: php oop object-oriented-analysis