关于使用哪种设计模式的问题

时间:2010-06-23 18:05:44

标签: c++ class-design

给出两个类:

第一类执行AES加密/解密,并在给定某个密钥和链的情况下返回加密/解密数据。

第二类收集要加密的数据,然后将其传递给加密/解密类。

从收集数据的类直接调用加密类或者是否应该在两个类之间有一个对象来进一步抽象该过程是否是正确的设计?我应该在程序的生命周期内有一个抽象类实例和一个加密实例来处理所有这些类型的请求吗?

2 个答案:

答案 0 :(得分:3)

就个人而言,我会创建一种表示加密算法的抽象接口,工厂函数接受密钥并生成加密算法的具体实例并安装密钥。因此,这里的“第二类”将直接调用“第一类”,但是会有一个“第三类”负责实例化该类。类似的东西:

/* Core encryption framework definitions */
class CipherInstance {
  // ...
  public:
    virtual void encrypt(void *, size_t) = 0;
    virtual void decrypt(void *, size_t) = 0;
    virtual size_t blocksize() const = 0;
// ...
    virtual ~CipherInstance() { }
};

class Cipher {
  public:
    virtual CipherInstance *instantiate(const void *key, size_t keylen) = 0;
    virtual size_t minkeysize() const = 0;
    virtual size_t maxkeysize() const = 0;
};

/* AES implementation */
class privateAESImpl : public Cipher { /* ... */ };
// This is the only public definition in the AES implementation. The privateAESImpl
// class is a stateless singleton, and this is the only instance. Doing this instead
// of static functions allows AES to be passed to a function taking a Cipher * 
extern privateAESImpl AES;

// Much later:
  CipherInstance *aes = AES.instantiate(key, keylen);
  aes->encrypt(data, datalen);
// or, to be more general:
void frob(Cipher *cipher, void *key, size_t keylen, void *data, size_t datalen) {
    CipherInstance *inst = cipher->instantiate(key, keylen);
    inst->encrypt(data, datalen);
}

C#的System.Security.Cryptography库使用类似的方法 - 例如,参见System.Security.Cryptography.SymmetricAlgorithm。但请注意,由于C#支持内省,因此不需要工厂类 - 而只需要a static method taking a name.使用C ++需要完整的工厂类。

答案 1 :(得分:1)

我会直接调用加密对象,但是通过接口。调用的实际加密对象将在运行时由控制程序的任何类提供。

你不得不原谅我,我的C ++生锈了......

// Interface for encryption.
class Encryptor
{
    public:
        virtual byte* encrypt(byte* data) = 0;
}

// Gathering class
class Gatherer
{
    private:
        Encryptor* encryptor;
    public:
        Gatherer(Encryptor* encryptor)
        {
            this->encryptor = encryptor;
        }

        void doStuff()
        {
            // Do stuff

            // Call encryption on gathered data
            byte* encryptedData = encryptor->encrypt(data);

            // Do more stuff with encrypted data.
        }
}

main()
{
    Encryptor* encryptor = new AESEncryptor(ENCRYPTION_KEY);
    Gatherer gatherer = new Gatherer(encryptor);
    gatherer->doStuff();
}
}