出于學習目的,我嘗試創建一個 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) ?
1 回答

白衣非少年
TA貢獻1155條經驗 獲得超0個贊
您需要按照您設置的順序展開。如果先壓縮然后加密,則需要解密然后解壓縮。
此特定代碼的快速修復方法是更改您的recuperar方法CompressaoDecorator
class CompressaoDecorator extends Decorator
{
public function recuperar($texto): string
{
return parent::recuperar($this->descomprimir($texto));
}
}
如果你想抽象地解決這個問題,我會用一個可以保證訂單的工廠來處理這個問題。為此,我認為單個對象本身不應該關心parent,工廠應該完成鏈接事物的工作。
編輯
實際上,當我更多地考慮這一點時,您不需要工廠,您只需將所有方法的順序交換即可recuperar,因此這個也會改變:
class CriptoDecorator extends Decorator
{
public function recuperar($texto): string
{
return parent::recuperar($this->decrypt($texto));
}
}
這應該允許您首先調用加密或壓縮,并且只要您使用相同的鏈,相反的操作也應該起作用。
- 1 回答
- 0 關注
- 147 瀏覽
添加回答
舉報
0/150
提交
取消