设计模式--策略模式
时间:2022-07-24
本文章向大家介绍设计模式--策略模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
模拟鸭子项目:
不使用设计模式的方案:
传统继承方式如下:
鸭子超类:
public abstract class Duck {
public void Quack() {
System.out.println("~~gaga~~");
}
public abstract void display();
public void swim() {
System.out.println("~~im swim~~");
}
}
GreenHeadDuck继承Duck :
public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("**GreenHead**");
}
}
同理可有RedHeadDuck等子类
应对新的需求,看看这个设计的可扩展性
1)添加会飞的鸭子
继承方式解决方案是:
public abstract class Duck {
...;
public void Fly() {
System.out.println("~~im fly~~");
}
};
问题来了,这个Fly让所有子类都会飞了,这是不科学的。
继承的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。影响会有溢出效应
继续使用继承方式解决方案是(覆盖父类方法):
public class GreenHeadDuck extends Duck {
...;
public void Fly() {
System.out.println("~~no fly~~");
}
}
又有新需求,石头鸭子,填坑(每个子类都要覆盖父类的方法):
public class StoneDuck extends Duck {
.... };
超类挖的一个坑,每个子类都要来填,增加工作量,复杂度O(N^2)。不是好的设计方式
需要新的设计方式,应对项目的扩展性,降低复杂度:
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?叫声、飞行...
用策略模式来解决新需求
接口:
public interface FlyBehavior
{
void fly();}
public interface QuackBehavior
{
void quack();};
好处:新增行为简单,行为类更好的复用,组合更方便。既有继承带来的复用好处,没有挖坑
重新设计的鸭子项目:
public abstract class Duck {
FlyBehavior mFlyBehavior;
QuackBehavior mQuackBehavior;
public Duck() { }
public void Fly() {
mFlyBehavior.fly();
}
public void Quack() {
mQuackBehavior.quack();
}
public abstract void display();
}
绿头鸭、石头鸭:
public class GreenHeadDuck extends Duck {
public GreenHeadDuck() {
mFlyBehavior = new GoodFlyBehavior(); //实现了飞行行为接口的类(可以多个)
mQuackBehavior = new GaGaQuackBehavior(); //实现了叫声接口的类(可以多个)
}
@Override
public void display() {...}
}
策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者。
经验:多用组合来实现设计。
更详细的解释参考:http://www.cnblogs.com/zuoxiaolong/p/pattern8.html
- 温故而知新:Delegate,Action,Func,匿名方法,匿名委托,事件
- 如何在Silverlight4中使用摄像头
- Flask的集中控制
- 64位IIS(IIS6/IIS7)上跑Asp + Jet.Oledb的设置要点
- windows 2003 32位系统能支持的最大内存数
- .Net Core内存回收模式及性能测试对比
- silverlight中顺序/倒序异步加载多张图片
- MySQL数据库性能优化之三
- 谁说 Java 要过时?2017年Java 大事件一览及未来前瞻
- mongodb的用法
- silverlight中如何将string(字符串)写入Resource(资源)?
- Python练习环境搭建-引入预定义数据
- 振幅和成交量的关系
- silverlight中的几个冷门标记 {x:Null},d:DesignWidth,d:DesignHeight
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 冒泡排序
- 详解linux下避免僵尸进程的几种方法
- Ubuntu下Subversion(SVN)的快速安装与配置详解
- Linux查看某个端口的连接数的方法
- 浅析Linux中使用nohup及screen运行后台任务的示例和区别
- 快速搭建简易、高效、多线程http服务器
- Linux解压文件到指定目录的方法
- Linux系统中CPU占用率较高问题排查思路与解决方法
- linux中ftp服务搭建需要注意的地方
- CentOS下使用LibreOffice实现文档格式的转换方式
- 详解在Linux中怎么使用cron计划任务
- Linux系统删除文件夹和文件的命令
- 详解Linux防火墙iptables禁IP与解封IP常用命令
- 在Ubuntu 16.04 Server上安装Zabbix的方法
- Centos7.3安装部署最新版Zabbix3.4的方法(图文)