【HeadFirst 设计模式学习笔记】1.策略模式

简介: 作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.书中举了一个鸭子类的设计,有些会飞或者会叫,有些不会飞可能也不会叫,用继承则导致不该有的功能通过继承而继承了下来,使用接口则代码无法做到最大程度的重用。

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

1.书中举了一个鸭子类的设计,有些会飞或者会叫,有些不会飞可能也不会叫,用继承则导致不该有的功能通过继承而继承了下来,使用接口则代码无法做到最大程度的重用。进而引出设计原则1:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起,把会变化的部分取出并封装起来,好让其他部分不会受到影响 。——每个设计模式背后的精神所在。

2.我们希望运行时动态的改变一些行为,这就引出了第二个原则:针对接口编程,而不是针对实现编程。 因此,鸭子的行为将被放在分开的类——我们可以将其叫做“行为类”中,此类专门提供某行为接口的实现。针对接口编程的意思是针对超类型编程——变量的声明类型应该是超类,通常是一个抽象类或者一个接口,如此,只要是具体实现此超类型的类所产生的对象,都可以指定给这个变量,这也意味着,声明类时不用理会以后执行时的真正对象类型。

针对实现编程
针对接口编程
更好的针对接口编程

Dog d=new Dog();
d.dark();
Animal animal=new Dog();
animal.makesound();
a = getAnimal();
a.makeSound();

不得不针对具体实现coding
利用animal多态处理
运行时才指定具体实现的对象

最后设计的样子是两个接口,一个飞,一个叫,每个接口中有相应的方法,然后设计不同的类对这个接口进行不同的实现。

然后在超类的设计中,行为变量被声明为“接口”类型的变量,然后具体动作的方法由接口类型的变量相对应的方法所实现。子类中,构造函数中指明这些接口类型的变量具体对应的是哪一个具体实现。这样的话,通过一个“接口”类型的变量,灵活性就更高了,虽然此时在构造函数中我们还是引入了具体实现。

3.进一步,我们希望可以自己设定具体的行为而不是在构造函数中写死,那么我们可以使用setter method,通过向外提供接口来设置从超类那继承的接口类型的成员变量。

4.最后我们看到的设计局面是:各种鸭子继承了Duck,飞行行为实现了FlyBehavior接口,呱呱叫行为实现了QuackBehavior接口。设计的基本理念在于行为不是继承而来的,而是通过适当的行为对象“组合”而来。这个总结就可以归纳出第三个设计原则:多用组合,少用继承。这样可使系统更具有弹性。

最后我们来看看这个模式的定义:

策略模式定义了算法簇,分别封装起来,让它们之间可以互相替换,此模式让方法的变化独立于使用方法的Client,适用于继承后的动作发生变化,要动态的改变对象的行为时。

核心思想:将is-a 转换为has-a.

基本的思路:将一些原先要继承的方法,以接口的方式抽象出来,然后再以实现该接口的方式定义一些类以完成实际能力的实现;同时在基类中以组合的方式将该接口的实例放入基类,基类同时提供设置这个实例的接口以及这个方法的封装,子类继承基类是对这些接口实例进行设置即可。

5.TIPs:

1)在开发中使用模式词汇,但是不要写一个helloworld都要扯上模式。

2)没有所谓设计模式库,只有设计模式条目。

3)模式并不只是利用了OO的设计原则。应用场景中若是没有合适的模式则使用最基本的OO原则。

附:鸭子的设计

建立不同的鸭子类 
fly行为
//  飞行接口 
public interface FlyBehavior {  
public void fly();  
}  
//  飞 
public class FlyWithWings implements FlyBehavior{  
public void fly() {  
        System.out.println("正在用翅膀飞行");  
    }  
}  
//  不飞 
public class FlyNoWay implements FlyBehavior{  
public void fly() {  
        System.out.println("不会飞");  
    }  
}  
//坐火箭飞 
public class FlyRocketPowered implements FlyBehavior{  
public void fly() {  
        System.out.println("坐火箭飞");  
    }  
}  
quack行为
//  叫接口 
public interface QuackBehavior {  
public void quack();  
}  
// 嘎嘎叫 
public class Quack implements QuackBehavior. {  
public void quack() {  
        System.out.println("嘎嘎叫");  
    }  
}  
//  吱吱叫 
public class Squeak implements QuackBehavior{  
public void quack() {  
        System.out.println("吱吱叫");  
    }  
}  
//  不叫 
public class MuteQuack implements QuackBehavior{  
public void quack() {  
        System.out.println("不会叫");  
    }  
} 
实现Duck类  
//  鸭子超类
public abstract class Duck {  
//  默认的行为 
FlyBehavior flyBehavior;  
    QuackBehavior quackBehavior;  

public Duck() {  
    }  
public void setFlyBehavior(FlyBehavior. fb) {  
        flyBehavior = fb;  
    }  
public void setQuackBehavior(QuackBehavior. qb) {  
        quackBehavior = qb;  
    }  
abstract void display();  
public void performFly() {  
        flyBehavior.fly();  
    }  
public void performQuack() {  
        quackBehavior.quack();  
    }  
public void swim() {  
        System.out.println("正在游泳~~");  
    }  
}  

//  野鸭  
     public class MallardDuck extends Duck {  
     public MallardDuck() {  
         quackBehavior = new Quack();  
                 flyBehavior = new FlyWithWings();  //这里也可以使用setFlyBehavior方法,下同!
     }  
     public void display() {  
         System.out.println("绿头鸭");  
     }  
}  
     //  红头鸭  
     public class RedHeadDuck extends Duck {  
     public RedHeadDuck() {  
         flyBehavior = new FlyWithWings();  
         quackBehavior = new Quack();  
     }  
     public void display() {  
         System.out.println("红头鸭");  
     }  
}  
     //  橡皮鸭  
    public class RubberDuck extends Duck {  
     public RubberDuck() {  
         flyBehavior = new FlyNoWay();  
         quackBehavior = new Squeak();  
     }  
     public void display() {  
         System.out.println("橡皮鸭");  
     }  
}  
     //模型鸭  
public class ModelDuck extends Duck {  
     public ModelDuck() {  
         flyBehavior = new FlyNoWay();  
         quackBehavior = new Quack();  
     }  
     public void display() {  
         System.out.println("模型鸭");  
     }  
}  

测试代码:

public class MiniDuckSimulator {  

public static void main(String[] args) {  

        MallardDuck    mallard = new MallardDuck();  
        RubberDuck    rubberDuckie = new RubberDuck();  
        RedHeadDuck    redHeadDuck = new RedHeadDuck();  

        ModelDuck    model = new ModelDuck();  

        mallard.performQuack();  
        rubberDuckie.performQuack();  
        redHeadDuck.performQuack();  

        model.performFly();      
        model.setFlyBehavior(new FlyRocketPowered());  
        model.performFly();  
    }  
}  

在线视频:http://v.youku.com/v_show/id_XMjU1NTI2OTEy.html

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/


               作者:gnuhpc
               出处:http://www.cnblogs.com/gnuhpc/
               除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


分享到:

目录
相关文章
|
30天前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
252 35
|
2月前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
|
6月前
|
设计模式 算法 Java
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
|
6月前
|
设计模式 算法 搜索推荐
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
137 14
|
9月前
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
297 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
11月前
|
设计模式 存储 缓存
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
|
12月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
132 1
|
6月前
|
设计模式 Java 数据库连接
【设计模式】【创建型模式】工厂方法模式(Factory Methods)
一、入门 什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法模式使类的实例化延迟
195 16
|
6月前
|
设计模式 负载均衡 监控
并发设计模式实战系列(2):领导者/追随者模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第二章领导者/追随者(Leader/Followers)模式,废话不多说直接开始~
201 0
|
6月前
|
设计模式 监控 Java
并发设计模式实战系列(1):半同步/半异步模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第一章半同步/半异步(Half-Sync/Half-Async)模式,废话不多说直接开始~
188 0

热门文章

最新文章