一帧数据 SpringApplication Jmeter Java Out Of Memory VMware facebook oop types enums threejs 百度seo关键词优化 npm安装vue js的点击事件 html好看的字体样式 idea中svn的使用 java解析pdf 小程序下拉刷新样式 python线程 python解析json数据 python3基础教程 python支持中文 python服务器开发 java队列 linux简介 网页游戏代码 嵌入式linux驱动程序设计从入门到精通 系统集成项目管理工程师教程 stl2stp pr黑场过渡 linux多线程编程 为什么英雄联盟无法连接服务器 git命令 PCCAD 猫眼电影票 淘宝图片下载 华为手机刷公交卡 mac版matlab ps怎么画漫画 linux格式化硬盘 jpg格式转换器
当前位置: 首页 > 学习教程  > 编程语言

设计模式学习(二十一)策略模式

2020/11/4 15:10:02 文章标签:

文章目录策略模式前言基本介绍具体的代码实现总结策略模式 前言 现在要求解决下面一个鸭子的问题: 用传统的方式来写就是创建一个鸭子的抽象类,然后野鸭,北京鸭,水鸭等继承这个抽象类来实现。 代码的实现: //鸭子的…

文章目录

  • 策略模式
    • 前言
    • 基本介绍
    • 具体的代码实现
    • 总结

策略模式

前言

  • 现在要求解决下面一个鸭子的问题:
    在这里插入图片描述
  • 用传统的方式来写就是创建一个鸭子的抽象类,然后野鸭,北京鸭,水鸭等继承这个抽象类来实现。
    在这里插入图片描述
  • 代码的实现:
//鸭子的抽象类
public abstract class Duck {

	public Duck() {
	
	}

	public abstract void display();//显示鸭子信息
	
	public void quack() {
		System.out.println("鸭子嘎嘎叫~~");
	}
	
	public void swim() {
		System.out.println("鸭子会游泳~~");
	}
	
	public void fly() {
		System.out.println("鸭子会飞翔~~~");
	}
	
}
//北京鸭子
public class PekingDuck extends Duck {

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("~~北京鸭~~~");
	}
	
	//因为北京鸭不能飞翔,因此需要重写fly
	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("北京鸭不能飞翔");
	}

}
//玩具鸭子
public class ToyDuck extends Duck{

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("玩具鸭");
	}

	//需要重写父类的所有方法
	
	public void quack() {
		System.out.println("玩具鸭不能叫~~");
	}
	
	public void swim() {
		System.out.println("玩具鸭不会游泳~~");
	}
	
	public void fly() {
		System.out.println("玩具鸭不会飞翔~~~");
	}
}
//野鸭子
public class WildDuck extends Duck {

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println(" 这是野鸭 ");
	}

}
  • 传统的方式实现的问题分析和解决方案:
    • 无论什么鸭子,只要继承了鸭子的抽象类,他们都会飞和叫,这是不合理的。而这一个问题就是继承所带来的问题,对类的局部改动,尤其超类的局部改动,会影响其他部分 ,会有溢出效应。
    • 解决上述的问题有两种方法,一种是覆盖fly方法或者叫的方法,但是这种方法比较麻烦,要是要成千上钟不同的情况,重写的就没有意义。还有一种方法就是策略模式。

基本介绍

  • 策略模式( Strategy Pattern )中,定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户,也就是让行为与使用者解耦。
  • 这算法体现了几个设计原则:
    • 第一:把变化的代码从不变的代码中分离出来
    • 第二:针对接口编程而不是具体类(定义了策略接口)
    • 第三:多用组合和聚合,少用继承(客户通过组合方式使用策略 )
  • 类图:
    在这里插入图片描述
    • 客户 context 有成员变量 strategy 或者其他的策略接口,至于需要使用到哪个策略,我们可以在构造器中指定。

具体的代码实现

  • 类图:
    在这里插入图片描述
  • 代码实现:
//飞行行为的接口
public interface FlyBehavior {
	public void fly();

}
public class GoodFlyBehavior implements FlyBehavior {

	@Override
	public void fly() {
		System.out.println("好的飞行");

	}

}
public class NoFlyBehavior implements FlyBehavior {

	@Override
	public void fly() {
		System.out.println("不会飞行");

	}

}
public class NormalFlyBehavior implements FlyBehavior {

	@Override
	public void fly() {
		System.out.println("一般的飞行");

	}

}
//发声的接口
public interface SpeakBehavior {
	public void speak();

}
public class GoodSpeakBehavior implements SpeakBehavior{

	@Override
	public void speak() {
		System.out.println("嘎嘎嘎嘎嘎!!!");		
	}

}
public class NoSpeakBehavior implements SpeakBehavior {

	@Override
	public void speak() {
		System.out.println("不会嘎嘎嘎嘎嘎!!!");

	}

}
//鸭子的抽象类
public abstract class Duck {
	
	//策略接口
	FlyBehavior fly;
	SpeakBehavior speak;
	
	public Duck() {
	
	}

	public abstract void display();//显示鸭子信息
	
	public void quack() {
		if(speak!=null) {
			speak.speak();
		}
	}
	
	public void fly() {
		if(fly!=null)
			fly.fly();
	}

	//传入策略
	public void setFly(FlyBehavior fly) {
		this.fly = fly;
	}

	public void setSpeak(SpeakBehavior speak) {
		this.speak = speak;
	}
	
	
	
}
//北京鸭子
public class PekingDuck extends Duck {

	public PekingDuck() {
		setFly(new NormalFlyBehavior());
		setSpeak(new GoodSpeakBehavior());
	}

	@Override
	public void display() {
		System.out.println("这是北京鸭子!!");
	}

}
//玩具鸭子
public class ToyDuck extends Duck{

	public ToyDuck() {
		setFly(new NoFlyBehavior());
		setSpeak(new NoSpeakBehavior());
	}
	@Override
	public void display() {
		System.out.println("这是玩具鸭!!!");
	}
}
//野鸭子
public class WildDuck extends Duck {

	public WildDuck() {
		setFly(new GoodFlyBehavior());
		setSpeak(new GoodSpeakBehavior());
	}
	@Override
	public void display() {
		System.out.println(" 这是野鸭!!! ");
	}

}
//客户端
public class Client {

	public static void main(String[] args) {
		//测试
		PekingDuck p = new PekingDuck();
		p.display();
		p.fly();
		p.quack();
		
		ToyDuck t = new ToyDuck();
		t.display();
		t.fly();
		t.quack();
		
		WildDuck w = new WildDuck();
		w.display();
		w.fly();
		w.quack();
		
		
	}

}
  • 结果:
    在这里插入图片描述

总结

  • 策略模式的关键是: 分析项目中变化部分与不变部分
  • 策略模式的核心思想是:多用组合聚合 ,少用继承;用行为类组合,而不是行为的继承,更有弹性
  • 体现了“ 对修改关闭,对扩展开放 ” 原则,客户端增加行为不用修改原有代码,只要添加一种策略( 或者行为 )即可避免了使用多重转移语句( if…else if…else)
  • 提供了可以替换继承关系的办法 (策略模式 )将算法封装在独立的 Strategy 类中使得你可以独立于其 Context 改变它,使它易于切换、易于理解、易于扩展
  • 需要注意的是:每添加一个策略就要增加一个类,当策略过多是会导致类数目庞大

本文链接: http://www.dtmao.cc/news_show_350353.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?