猿问

PHP如何使用Decorator模式解密后使用解压?

出于学习目的,我尝试创建一个 GoF Decorator 实现,以将文本转换为压缩文本或加密文本的可能性为例。


    <?php

    interface DataSource {

        public function gerar($texto): string;

        public function recuperar($texto) : string;

    }

    class TextoBase implements DataSource {

        public function gerar($texto): string {

            return $texto;

        }

        public function recuperar($texto) : string {

            return $texto;

        }

    }

    abstract class Decorator implements DataSource {

        private DataSource $decorado;

        public function __construct(DataSource $decorado) {

            $this->decorado = $decorado;

        }

        public function gerar($texto): string {

            return $this->decorado->gerar($texto);

        }

        public function recuperar($texto) : string {

            return $this->decorado->recuperar($texto);

        }

    }

   class CriptoDecorator extends Decorator {


    const KEY = 'vDIa5JdknBqfrKOu8d7UpddnBMCH1vza';

    const NONCE = 'Ra5LeH7ntW2rvkz3dmqI5Stx';


    public function gerar($texto): string {

        return $this->encrypt(parent::gerar($texto));

    }


    public function recuperar($texto): string {

        return $this->decrypt(parent::recuperar($texto));

    }


    public function encrypt($data) {

        return sodium_crypto_secretbox($data, self::NONCE, self::KEY);

    }


    private function decrypt(string $data): string {

        return sodium_crypto_secretbox_open($data, self::NONCE, self::KEY);

    }


}

    class CompressaoDecorator extends Decorator {

        const NIVEL_COMPRESSAO = 6;

        public function gerar($texto): string {

            return $this->comprimir(parent::gerar($texto));

        }

由于某种原因,我收到警告:


Warning: gzuncompress(): data error in C:\wamp64\www\curso\designer_patterns\estrutural\decorator\real_life.php on line 93

那么,有没有办法解决这个问题并允许两个装饰器堆叠并用于 gerar(generate) 和 recuperar(retrieve) ?


一只斗牛犬
浏览 117回答 1
1回答

白衣非少年

您需要按照您设置的顺序展开。如果先压缩然后加密,则需要解密然后解压缩。此特定代码的快速修复方法是更改您的recuperar方法CompressaoDecoratorclass CompressaoDecorator extends Decorator{&nbsp; &nbsp; public function recuperar($texto): string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return parent::recuperar($this->descomprimir($texto));&nbsp; &nbsp; }}如果你想抽象地解决这个问题,我会用一个可以保证订单的工厂来处理这个问题。为此,我认为单个对象本身不应该关心parent,工厂应该完成链接事物的工作。编辑实际上,当我更多地考虑这一点时,您不需要工厂,您只需将所有方法的顺序交换即可recuperar,因此这个也会改变:class CriptoDecorator extends Decorator{&nbsp; &nbsp; public function recuperar($texto): string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return parent::recuperar($this->decrypt($texto));&nbsp; &nbsp; }}这应该允许您首先调用加密或压缩,并且只要您使用相同的链,相反的操作也应该起作用。
随时随地看视频慕课网APP
我要回答