策略模式:帮助构建的对象不必自身包含逻辑,而是能够根据需要利用其他对象中的算法。
举个例子:
我们常用的加密算法有DES(对称加密)和AES(非对称加密),假如现在我们有一个报文Context需要加密,加密的方法不固定,可能使用DES,也可能使用AES,实现这个需求有两种方法。
第一种方法就是在Context类中定义两个加密算法(DES和AES),然后直接调用Context类中的加密方法来完成加密,这是可以实现的,但是如果又新增一种加密算法(MD5),那么就得修改Context类了,根据开闭原则,这是不推荐的。
另一种方法就是使用策略模式,即将DES和AES等多种加密方法声明为单独的策略类,然后再Context里面设置要使用哪种策略,然后再用那种策略加密即可,并不需要向刚刚那个方法那样,还得在Context类中定义很多复杂的方法,他只需要调用其他类的方法即可,拿来主义,这就是策略模式。
下面这个代码,是用方法一:
<?php class Context{ private $info;//要加密的内容 public function __construct($info){ $this->info=$info;//设置要加密的信息 } //定义DES加密 public function DESencrypt(){ echo "the info is {$this->info} ,encrypting it with DES "; } //定义AES加密 public function AESencrypt(){ echo "the info is {$this->info} ,encrypting it with AES "; } } $context=new Context("Hello World"); //使用自身的des策略 $context->DESencrypt(); //输出the info is Hello World ,encrypting it with DES //使用自身的aes加密 $context->AESencrypt(); //输出the info is Hello World ,encrypting it with AES ?>
上面的方法虽然简单易懂,但是灵活性差,一旦增加一种新的加密方法,就会修改Context类。
下面使用策略模式实现:
<?php //添加一个AES的策略类 class DES{ public function encrypt($info){ echo "the info is {$info} ,encrypting it with DES "; } } //添加一个AES的策略类 class AES{ public function encrypt($info){ echo "the info is {$info} ,encrypting it with AES "; } } class Context{ private $info;//要加密的内容 private $enc_type;//加密方法 public function __construct($info){ $this->info=$info;//设置要加密的信息 } //选择加密的方法(策略) public function set_enc_type($type){ $this->enc_type=$type; } //用已经选定的策略,执行加密操作 public function ToDo(){ $this->enc_type->encrypt($this->info); } } $context=new Context("Hello World"); //使用des策略 $des=new DES(); $context->set_enc_type($des); $context->ToDo(); //输出the info is Hello World ,encrypting it with DES //使用aes策略 $aes=new AES(); $context->set_enc_type($aes); $context->ToDo(); //输出the info is Hello World ,encrypting it with AES ?>