设计模式-策略模式(strategy)
- 格式:ppt
- 大小:978.06 KB
- 文档页数:16


ES6设计模式之策略模式
策略模式的本质,也是设计模式的本质,是将易变化的部分分离出去,不管是对象和对象的⾏为分离,还是对象和对象表现分离等,都遵循。这是最基本的设计原则。然后把他们组合到⼀起,⽣成你需要的,不要管那么多设计原则,最终的⽬的是好维护,易读懂。class Duck{ constructor(id){ = id; } getid(){ console.log(); }
display(){ console.log(“a nomal duck”); } }
class FlyBefavior{ constructor(wings){ this.wings = wings; } fly(){ console.log(fly with ${ this.wings}!); } }
class QuackBefavior{ constructor(sound){ this.sound = sound; } quack(){ console.log(duck make sound,${this.sound}); } }
class swimBefavior{ constructor(){
} swim(){ console.log(“duck swim in water.”); } }
class MallardDuck extends Duck{ constructor(id){ super(id); this.mallfly = new FlyBefavior(“green wings”); this.mallquack = newQuackBefavior(“gua gua gua”); }
fly(){ this.mallfly.fly(); }
quack(){ this.mallquack.quack() }
display(){ console.log(‘yee,a green head duck.’); } }
责任链策略+策略模式组合
责任链模式(Chain of Responsibility Pattern)和策略模式(Strategy Pattern)都是设计模式中的重要组成部分,可以有效地解决一些特定的问题。将两者组合使用,可以在责任链的每个节点上应用不同的策略,从而实现策略的动态切换和组合。
在责任链模式中,多个对象可以处理请求,但只有一个对象能够处理请求并返回结果。其他对象则将请求传递给下一个对象,直到某个对象处理了请求。这种模式可以用于解耦对象之间的依赖关系,使得请求的传递和处理更加灵活。
策略模式则允许将算法独立于使用它的客户端而变化。它定义了一系列算法,并将每个算法封装起来,使得它们可以互相替换。策略模式使得算法可以独立于使用它的客户端而变化,从而提高了系统的灵活性和可扩展性。
将责任链模式和策略模式组合使用,可以在责任链的每个节点上应用不同的策略。这样,客户端只需要与链中的一个节点进行交互,就可以使用不同的策略。客户端只需要知道特定节点的接口,而不必关心其他节点的具体实现。这样可以使系统的实现更加灵活,也方便了系统的扩展和维护。
具体实现时,可以按照以下步骤进行:
1. 定义抽象策略:创建一个接口,定义一些方法来处理不同的任务或操作。
2. 定义多个策略类:实现抽象策略接口,并实现各自的方法。这些策略类将根据不同的需求实现不同的算法或行为。 3. 创建责任链:定义一个责任链接口和实现类,责任链接口包含一些方法用于处理请求,这些方法会将请求传递给链中的下一个对象。
4. 在客户端中使用责任链:客户端只需要与链中的一个节点进行交互,就可以使用不同的策略。
通过这种方式,客户端可以根据需要选择不同的策略,而无需修改客户端代码。同时,这种组合使用也使得系统的实现更加灵活和可扩展。
1 策略模式(Strategy)
1 场景问题
1.1 报价管理
向客户报价,对于销售部门的人来讲,这是一个非常重大、非常复杂的问题,对不同的客户要报不同的价格,比如:
对普通客户或者是新客户报的是全价
对老客户报的价格,根据客户年限,给予一定的折扣
对大客户报的价格,根据大客户的累计消费金额,给予一定的折扣
还要考虑客户购买的数量和金额,比如:虽然是新用户,但是一次购买的数量非常大,或者是总金额非常高,也会有一定的折扣
还有,报价人员的职务高低,也决定了他是否有权限对价格进行一定的浮动折扣
甚至在不同的阶段,对客户的报价也不同,一般情况是刚开始比较高,越接近成交阶段,报价越趋于合理。
总之,向客户报价是非常复杂的,因此在一些CRM(客户关系管理)的系统中,会有一个单独的报价管理模块,来处理复杂的报价功能。
为了演示的简洁性,假定现在需要实现一个简化的报价管理,实现如下的功能:
(1)对普通客户或者是新客户报全价
(2)对老客户报的价格,统一折扣5%
(3)对大客户报的价格,统一折扣10%
该怎么实现呢?
1.2 不用模式的解决方案
要实现对不同的人员报不同的价格的功能,无外乎就是判断起来麻烦点,也不多难,很快就有朋友能写出如下的实现代码,示例代码如下:
/**
* 价格管理,主要完成计算向客户所报价格的功能
*/ 2 public class Price {
/**
* 报价,对不同类型的,计算不同的价格
* @param goodsPrice 商品销售原价
* @param customerType 客户类型
* @return 计算出来的,应该给客户报的价格
oop的三种设计模式(单例、⼯⼚、策略)
单例模式:
废话不多说,我们直接上代码:
我们可以看到,结果为:两个实例化出来对象是⼀样的。这就体现了我们单例的精髓(只能实例化出来⼀个实例,并且不可复制,能够节省系统资源)注意:静态变量上存在内存中的,它不会因为程序执⾏完毕⼆消失,所以我们第⼆次实例化的时候,会检测到instance的存在,因⽽直接返回已经存在的instance实例。下⾯我们来看⼀下单例的实际运⽤:⽤于数据库连接类,因为是数据库连接,我们没有必要每⼀次操作数据库都进⾏⼀次数据库类的实例化,那样会⼤⼤的消耗系统资源。所以,我们⽤到了单例模式,代码如下:
//初始化连接参数private function initParam($config){$this->host=isset($config['host'])?$config['host']:'';$this->port=isset($config['port'])?$config['port']:'3306';$this->user=isset($config['user'])?$config['user']:'';$this->pwd=isset($config['pwd'])?$config['pwd']:'';$this->charset=isset($config['charset'])?$config['charset']:'utf8';$this->dbname=isset($config['dbname'])?$config['dbname']:'';
}private function connect(){$this->link=@mysql_connect("{$this->host}:{$this->port}",$this->user,$this->pwd) or die('数据库连接失败');}
private function setCharset(){$sql = "set names '{$this->charset}'";$this->query($sql);}private function selectDB(){$sql = "use `{$this->dbname}`";$this->query($sql);}private function __construct($config){$this->initParam($config);$this->connect();$this->setCharset();$this->selectDB();}private function __clone(){