拆分大型类或为单个函数调用完全加载它们


Split large classes or load them entirely for a single function call?

我想知道是否值得将一个大型类分成不同的部分,并且仅在需要时使用它们。如果是的话,最好的选择是什么?

我不确定在PHP文件中使用一个大的类对资源的影响,当启用缓存时,它的使用非常有限。也许这就是不值得,不管这个班有多大?

我脑海中有两个模型…这需要能够影响"父"变量。我完全意识到这段代码不会工作,我只是想我应该在PHP+pseudo中输入它来解释它,而不是单独的伪代码。
class User {
    public $id;
    public $password;
    public $password_hash;
    public $post_count;
    public function __construct($id) {
        $this->id = $id;
    }
}
subclass Password of User {
    public function set($password) {
        parent::$password = $password; }
    public function generateHash() {
        parent::$password_hash = hash("sha256", parent::$password, true); }
    public function validate($password) {
        return (hash("sha256", $password, true) === parent::$password_hash); }
}
subclass Post of User {
    public function count() {
        $db = ConnectionFactory::getFactory()->getConnection();
        $sql = $db->prepare("SELECT 1 FROM `Forum_Posts` WHERE `User_ID`=:user");
        $sql->execute(array('user' => parent::$id));
        parent::$post_count = $sql->rowCount();
        return parent::$post_count;
    }
}
$some_bloke = new User(3);
$bob = new User(4);
$bob->Password->set('idonthaveaverygoodpassword');
$bob->Password->generateHash();
$lucy = new User(5);
echo $lucy->Post->count();

我也考虑过使用多个特征,但这不是一个漂亮的解决方案,我担心它会毫无意义地增加内存使用:

class User {
    use BaseUser;
}
class User_Password {
    use BaseUser;
    use Password;
}
class User_Post {
    use BaseUser;
    use Post;
}
trait BaseUser {
    public $id;
    public $password;
    public $password_hash;
    public $post_count;
    public function __construct($id) {
        $this->id = $id;
    }    
}
trait Password {
    //stuff
}
trait Post {
    //stuff
}
$some_bloke = new User(3);
$bob = new User_Password(4);
$bob->setPassword('idonthaveaverygoodpassword');
$bob->generatePasswordHash();
$lucy = new User(5);
echo $lucy->countPosts();

我也非常开放的建议,什么重命名这篇文章。我只是不太确定

一个通用框架称为SOLID,它可以帮助实现与领域无关的OOP。通过尝试遵守它所定义的每个原则,它通常可以应用于任何领域。也就是说,SOLID只是一个框架,代码可以实现坚实的原则,但仍然很难使用:(我将尝试用它在您的领域的一个相当通用的应用来回答:

单一职责每个类是否只有一个改变的理由?如果哈希算法或盐改变了,它会被隔离到一个单独的点吗?是的。如果需求发生了变化,而组织不想在内存中保存原始密码,该怎么办?不。用户和密码都需要修改

打开/关闭我们如何创建新类型的帖子、用户或密码?如果企业想要添加一个不需要密码的未经身份验证的用户,该怎么办?可以在不修改User模型的情况下在系统中建模吗?如果未经身份验证的用户总是0个帖子呢?

Liskov替换这表明,所有对象都应该可以用其子类型的实例替换。通常只有在创建了使用域对象的代码之后才会验证这一点。在本例中:

$some_bloke = new User(3);
$bob = new User(4);
$bob->Password->set('idonthaveaverygoodpassword');
$bob->Password->generateHash();
$lucy = new User(5);
echo $lucy->Post->count();

如果$bobPost的实例,则不能使用Password (User的子类)实例化,$lucyPassword的实例而不是User

接口隔离

依赖倒置


总的来说,我觉得内存使用应该不是高级(非嵌入式)应用程序的问题。我发现,即使对于移动设备,抽象和可维护性也比最小化内存使用更重要。

此外,基于继承的层次结构很容易变得笨拙和脆弱。组合(更像你的第二个建议)可能有助于实现SOLID和最小化脆性。可以为用户提供密码策略,该策略将定义用于生成密码的接口,并允许更改密码生成实现,而不影响用户。想要生成密码的用户可以委托他们的特定策略。