扩展+实现,关于良好设计原则的问题

时间:2011-09-13 09:18:26

标签: php interface

---代码改变了---

假设我有一个接口和两个类,其中一个扩展另一个类:

interface EncryptionModule {
    public function setup();

    public function encrypt($originalString);

    public function decrypt($encryptedString);
}

class GeneralOneWayHashingModule {
    public static $encryptionType = ALG_TYPE_HASH_FUNCTION;
    protected $salt;

    public function setSalt($salt) {
        $this->salt = $salt;
    }


    public function decrypt($encryptedString) {
        throw new Exception(__CLASS__ . ' ' . __LINE__ . ': cannot reverse an hash function ');
    }
}

class BCryptHashingModule extends GeneralOneWayHashingModule implements GeneralOneWayHashingModule {
    protected $cost;

    public function setup() {
        $this->cost = 10;
    }

    public function setCost($cost) {
        $this->cost = $cost;
    }

    public function encrypt($originalString) {
        return crypt($originalString, '$2a$' . str_pad($this->cost, 2, '0', STR_PAD_LEFT) . '$' . $this->salt);
    }
}

我想知道这两个类中哪一个应该实现EncryptionModule接口..扩展一个(这是我的选择)?这两个类,可能将GeneralOneWayHashingModule声明为abstract并实现EncryptionModule中声明的所有函数?只有扩展的一个?

感谢。

2 个答案:

答案 0 :(得分:1)

GeneralOneWayHashingModule是否应该是抽象的问题与另一个问题无关:是否应该实现此接口。两者的答案是:它取决于类的Responsibilities,是否打算实例化,可能other decisions

如果我知道每个班级的用途以及它有哪些方法,我可以给出更好的答案。

代码更新后

编辑

我在这里看到几个问题:

  • 为什么要打电话给 ...模块?我不认为它是一个模块,而是一个普通的课程。它的职责是加密东西。我宁愿称之为Encryption(名字对我来说非常重要,他们会告诉我这个课程的用途,即使我专注于其他事情 - 通常情况下,当我使用课程时)
  • 正如Carlos在对您的问题的评论中正确指出加密!=哈希和加密根据定义是可反转的,而散列不是,这两个类不应该相互扩展。
  • setup()功能的目的是什么?我认为你添加了这个函数,因为你注意到一些子类需要它来实现它。问题应该是:所有加密功能都有一个设置程序吗?这是强制性的吗?我不这么认为。
  • 您遇到的另一个问题是您希望某些加密例程使用salt,而其他加密例程似乎不需要使用salt。由于盐通常不会被重复使用(即您通常每次加密都有一个新的盐),它不应该是类成员,否则您的类具有状态,这不是您想要的(即$encryption不能再连续encrypt()个2个字符串,必须更改其状态 - 必须调用setSalt() - 因为它可以加密第二个字符串)。
  • 但真正的问题是:你需要这个类结构?用于测试/展示不同的算法或存储/验证密码?如果您只想实施密码验证,那么您过度工程化,您可能更喜欢使用以下内容:
    class User {
        public function encryptPassword($password, $salt) {
            // …
        }
        public function verifyPassword($password, $salt, $encryptedPassword);
            return $encryptedPassword == self::encryptPassword($password, $salt);
        }
    }
    

答案 1 :(得分:0)

它取决于从GeneralOneWayHashingModule继承的其他类,如果它们都实现了EncryptionModule接口,那么GeneralOneWayHashingModule也应该“实现”它。

顺便说一句,如果GeneralOneWayHashingModule“实现”EncryptionModule,那么BCryptHashingModule“也实现”它,因为它继承了它(“扩展”关键字)

相关问题