责任链模式
- 定义
为请求创建一个接收此次请求的链 - 适用场景
一个请求的处理需要多个对象当中的一个或几个协作处理 - 优点
请求的发送者和接收者(请求的处理)解耦
责任链可以动态组合 - 缺点
责任链太长或者处理时间过长,影响性能
责任链有可能过多
/**处理者--或者Approver
* @author MrPeng
* @date 2019/2/21
*/
public class Handler {
protected Handler handler;
/**
* 设置下一个处理者
*/
public void setNextHandler(Handler handler){
this.handler = handler;
}
/**
* 处理方法
*/
public abstract void handle(HomeWork homeWork);
}
------------------------------------------------
public class HomeWork {
private String chinese;
private String math;
private String english;
//get/set等省略
}
------------------------------------
//其他类似
public class MathHandler extends Handler {
@Override
public void handle(HomeWork homeWork) {
if (homeWork.getMath() != null) {
System.out.println("写了数学作业,检查通过");
if (handler != null) {
handler.handle(homeWork);
}
} else {
System.out.println("没写数学作业,检查不通过--流程结束");
return;
}
}
}
-----------------------------------
public static void main(String[] args) {
ChineseHandler chineseHandler = new ChineseHandler();
MathHandler mathHandler = new MathHandler();
EnglishHandler englishHandler = new EnglishHandler();
HomeWork homeWork = new HomeWork();
// homeWork.setChinese("语文");
//homeWork.setMath("数学");
homeWork.setEnglish("英语");
//chineseHandler作为第一个处理者,分配下一个处理者mathHandler
chineseHandler.setNextHandler(mathHandler);
//mathHandler也分配下一个处理者englishHandler
mathHandler.setNextHandler(englishHandler);
//形成一个责任链-由第一个处理者发起执行流程
//先检查语文-ok-检测数学-ok-检查英语
chineseHandler.handle(homeWork);
}
命令模式
-
定义
将“请求”封装成对象,以便使用不同的请求
命令模式解决了应用程序中对象的职责以及它们之间的通信方式 -
适用场景
请求调用者和请求接收者需要解耦,使得调用者和接收者不直接交互
需要抽象出等待执行的行为 -
优点
降低耦合
容易扩展新命令或一组命令 -
缺点
命令的无限扩展会增加类的数量,提高系统实现复杂度
/**命令接口
* @author MrPeng
* @date 2019/2/20
*/
public interface Command {
void execute();
}
--------------------------
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
-------------------------------------
/**吃饭命令
* @author MrPeng
* @date 2019/2/20
*/
public class EatCommand implements Command{
private Person person;
public EatCommand(Person person) {
this.person = person;
}
@Override
public void execute() {
person.eat();
}
}
----------------------------
/**执行人
* @author MrPeng
* @date 2019/2/20
*/
public class Master {
/**
* 定义一个数组存放命令
*/
private List<Command> commandList = new ArrayList<>();
/**
* 添加命令
*/
public void addCommand(Command command){
commandList.add(command);
}
/**
* 批处理
*/
public void executeBatch(){
for (Command command : commandList) {
command.execute();
}
commandList.clear();
}
}
---------------------------------
public static void main(String[] args) {
Master master = new Master();
Person ranger = new Person("Ranger");
EatCommand eatCommand = new EatCommand(ranger);
SleepCommand sleepCommand = new SleepCommand(ranger);
master.addCommand(eatCommand);
master.addCommand(sleepCommand);
master.executeBatch();
}
解释器模式
- 定义
给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
为解释一种语言,而为语言创建的解释器 - 适用场景
某个特定类型问题发生频率足够高(使用较少) - 优点
语法由很多类表示,容易改变及扩展此“语言” - 缺点
当语法规则数太多时,增加系统复杂度
UML类图
自定义一种AND和OR的规则解释器:3个String类型操作数 v1,v2,v3
操作数解释规则,当传入和字符串里包含自身,返回true,否则返回false
AND 返回 v1.interpret(v3) && v2.interpret(v3)
OR 返回 v1.interpret(v3) || v2.interpret(v3)
/**解释器接口
* @author MrPeng
* @date 2019/2/18
*/
public interface Expression {
boolean interpret(String context);
}
-----------------------------------
/**与AND表达式自定义实现
* @author MrPeng
* @date 2019/2/18
*/
public class AndExpression implements Expression {
private Expression expr1;
private Expression expr2;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
@Override
public String toString() {
return expr1+" (自定义AND) " +expr2;
}
}
-------------------------------------
/**或OR表达式自定义实现
* @author MrPeng
* @date 2019/2/18
*/
public class OrExpression implements Expression {
private Expression expr1;
private Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
@Override
public String toString() {
return expr1+" (自定义OR) " +expr2;
}
}
----------------------------------------
/**变量解释规则自定义实现
* @author MrPeng
* @date 2019/2/18
*/
public class ValueExpression implements Expression {
private String data;
public ValueExpression(String data){
this.data = data;
}
/**
* 解释规则:当传入和字符串里包含data子串,返回true,否则返回false
* @param context String
* @return boolean
*/
@Override
public boolean interpret(String context) {
if(context.contains(data)){
return true;
}
return false;
}
@Override
public String toString() {
return data;
}------------------------------------------------
public static void main(String[] args) {
Expression value1 = new ValueExpression("aaa");
Expression value2 = new ValueExpression("bbb");
Expression and = new AndExpression(value1, value2);
Expression or = new OrExpression(value1, value2);
System.out.println(and + " = " +and.interpret("ccc"));
System.out.println(and + " = " +and.interpret("aaabbb"));
System.out.println(or + " = " +or.interpret("aaabbb"));
}
------------------------------------------
aaa (自定义AND) bbb = false
aaa (自定义AND) bbb = true
aaa (自定义OR) bbb = true
迭代器模式
- 定义
提供一种方法,顺序访问一个集合对象的各个对象,而又不暴露该对象的内部表示 - 适用场景
访问一个集合对象的内容而无需暴露它的内部表示
为遍历不同集合结构提供统一集接口(自己编写迭代器较少,通常使用jdk提供好的) - 优点
分离了集合对象的遍历行为 - 缺点
类的个数成对增加
中介者模式
- 定义
定义一个封装 一组对象如何交互 的对象
通过使对象明确地相互引用来促进松散耦合,并允许独立地改变它们的交互 - 适用场景
系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解
交互的公共行为,如果需要改变行为则可以增加新的中介者类 - 优点
将一对多转化成了一对一,降低程序复杂度
类之间解耦 - 缺点
中介者过多导致系统复杂
public class Person {
private String name;
/**
* 发送消息
*/
public void sendMessage(String message){
StudyGroup.showMessage(this,message);
}
//构造方法 get/set省略
}
-------------------------------
//中介者
public class StudyGroup {
/**
* 展示消息
*/
public static void showMessage(Person person , String message){
System.out.println(new Date().toString()+"["+person.getName()+"]"+message);
}
}
------------------------------
public static void main(String[] args) {
Person person1 = new Person("aaa");
Person person2 = new Person("bbb");
person1.sendMessage("你好 bbb");
person2.sendMessage("你好 aaa");
}
备忘录模式
- 定义
保存一个对象的状态,以便在适当的适合恢复(后悔药) - 适用场景
保存及恢复数据相关业务场景
后悔的时候,即可恢复到之前的状态 - 优点
为用户提供一种可恢复的机制
存档信息的封装 - 缺点
资源占用
/**文章类
* @author MrPeng
* @date 2019/2/20
*/
public class Article {
private String title;
private String content;
//省略get/set/toString
public Article(String title, String content) {
this.title = title;
this.content = content;
}
/**
* 生成快照-备份对象
*/
public ArticleMemo saveToMemo(){
return new ArticleMemo(title, content);
}
/**
* 撤回
*/
public void undoFromMemo(ArticleMemo articleMemo){
this.title = articleMemo.getTitle();
this.content = articleMemo.getContent();
}
}
-------------------------------------------------
/**文章快照-备份
* @author MrPeng
* @date 2019/2/20
*/
public class ArticleMemo {
private String title;
private String content;
//只有get/toString
public ArticleMemo(String title, String content) {
this.title = title;
this.content = content;
}
}
-------------------------------------------------
/**文章快照记录管理
* @author MrPeng
* @date 2019/2/20
*/
public class ArticleMemoManager {
/**
* 定义一个栈存放快照记录
*/
private final Stack<ArticleMemo> ARTICLE_MEMO_STACK = new Stack<>();
/**
* 获取快照对象-出栈
*/
public ArticleMemo getMemo(){
return ARTICLE_MEMO_STACK.pop();
}
/**
* 记录快照-入栈
*/
public void addMemo(ArticleMemo articleMemo){
ARTICLE_MEMO_STACK.push(articleMemo);
}
}
-------------------------
public static void main(String[] args) {
ArticleMemoManager manager = new ArticleMemoManager();
Article article = new Article("第一次写的", "还没想好");
System.out.println("原纪录: "+article);
ArticleMemo articleMemo = article.saveToMemo();
System.out.println("第一份快照记录: "+articleMemo);
manager.addMemo(articleMemo);
article.setTitle("第一次写的+第二次写的");
article.setContent("还没想好+第二次写的");
articleMemo = article.saveToMemo();
System.out.println("第二份快照记录: "+articleMemo);
manager.addMemo(articleMemo);
article.setTitle("第一次写的+第二次写的+第三次写");
article.setContent("还没想好+第二次写的+第三次写");
articleMemo = article.saveToMemo();
System.out.println("第二份快照记录: "+articleMemo);
manager.addMemo(articleMemo);
articleMemo = manager.getMemo();
article.undoFromMemo(articleMemo);
System.out.println("暂存回退开始:"+article);
articleMemo = manager.getMemo();
article.undoFromMemo(articleMemo);
System.out.println("第一次撤销操作:"+article);
articleMemo = manager.getMemo();
article.undoFromMemo(articleMemo);
System.out.println("第二次撤销操作:"+article);
}
观察者模式
- 定义
定义了对象之间的一对多依赖,让多个观察者对象同时监听一个主题对象,当对象主题发生变化时,它的所有依赖(观察者)都会收到通知并更新 - 适用场景
关联行为场景,建立触发机制 - 优点
观察者和被观察者之间建立了一个抽象的耦合
观察者模式支持广播通信 - 缺点
观察者之间有过多的细节依赖,提高时间消耗和程序复杂度
使用要得当,要避免循环调用
/**
* 课程--继承Observable 成为被观察者
* @author MrPeng
* @date 2019/2/19
*/
public class Course extends Observable {
private String name;
public Course(String name) {
this.name = name;
}
//get/set忽略
public void produceQuestion(Course course, Question question){
System.out.println(question.getPersonName()+"在"+course.name+"中提出了一个问题,内容是:"+question.getContent());
//设置被观察者行为状态发送改变
setChanged();
//通知其他观察者,可以传递一些参数给观察者,会被update方法接收
notifyObservers(question);
}
}
/**
* 问题
* @author MrPeng
* @date 2019/2/19
*/
public class Question {
private String personName;
private String content;
//get/set忽略
}
----------------------------------------------
/**老师--实现Observer 成为观察者
* @author MrPeng
* @date 2019/2/19
*/
public class Teacher implements Observer {
private String name;
public Teacher(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
Course course = (Course)o;
Question question = (Question)arg;
System.out.println(name+"老师的"+course.getName()+"课程收到一个问题:提问者:"+question.getPersonName()+" 内容是:"+question.getContent());
}
}
-------------------------------------------------
public static void main(String[] args) {
Course course = new Course("Java设计模式");
Teacher teacher = new Teacher("Ranger");
Teacher teacher1 = new Teacher("Singwa");
//添加观察者-可多个
course.addObserver(teacher);
course.addObserver(teacher1);
Question question = new Question();
question.setPersonName("AAA");
question.setContent("观察者模式有什么优点?");
course.produceQuestion(course,question);
}
状态模式
- 定义
允许一个对象在其内部状态改变时,改变它的行为 - 适用场景
一个对象存在多种状态(不同状态下行为不同),且状态可相互转换 - 优点
将不同的状态隔离
把各种状态的转换逻辑,分布到State的子类中,减少相互间的依赖
增加新的状态非常简单 - 缺点
状态多的业务场景导致类的数目增加,系统变复杂
/**视频状态
* @author MrPeng
* @date 2019/2/21
*/
public abstract class VideoState {
protected VideoContext videoContext;
/**
* 设置视频上下文
*/
public void setVideoContext(VideoContext videoContext) {
this.videoContext = videoContext;
}
public abstract void play();
public abstract void speed();
public abstract void pasue();
public abstract void stop();
}
/**视频上下文
* @author MrPeng
* @date 2019/2/21
*/
public class VideoContext {
private VideoState videoState;
public final static PlayState PLAY_STATE = new PlayState();
public final static SpeedState SPEED_STATE = new SpeedState();
public final static PauseState PAUSE_STATE = new PauseState();
public final static StopState STOP_STATE = new StopState();
public VideoState getVideoState() {
return videoState;
}
/**
* 设置视频状态--并应用上下文
*/
public void setVideoState(VideoState videoState) {
this.videoState = videoState;
this.videoState.setVideoContext(this);
}
public void play(){
this.videoState.play();
}
public void speed(){
this.videoState.speed();
}
public void pause(){
this.videoState.pasue();
}
public void stop(){
this.videoState.stop();
}
}
--------------------------------------------
/**播放状态
* @author MrPeng
* @date 2019/2/21
*/
public class PlayState extends VideoState{
@Override
public void play() {
System.out.println("正常播放");
}
@Override
public void speed() {
super.videoContext.setVideoState(VideoContext.SPEED_STATE);
}
@Override
public void pasue() {
super.videoContext.setVideoState(VideoContext.PAUSE_STATE);
}
@Override
public void stop() {
super.videoContext.setVideoState(VideoContext.STOP_STATE);
}
}
---------------------------------
public static void main(String[] args) {
VideoContext context = new VideoContext();
context.setVideoState(new PlayState());
System.out.println("当前状态:"+context.getVideoState().getClass().getSimpleName());
context.pause();
System.out.println("当前状态:"+context.getVideoState().getClass().getSimpleName());
context.play();
System.out.println("当前状态:"+context.getVideoState().getClass().getSimpleName());
context.speed();
System.out.println("当前状态:"+context.getVideoState().getClass().getSimpleName());
context.stop();
System.out.println("当前状态:"+context.getVideoState().getClass().getSimpleName());
context.pause();
}
----------------------------
当前状态:PlayState
当前状态:PauseState
当前状态:PlayState
当前状态:SpeedState
当前状态:StopState
播放结束 不能暂停
策略模式
- 定义
定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户
处理方法中大量的if/else - 适用场景
系统中有很多类,而他们的区别仅仅在于他们的行为不同
一个系统需要动态地在几种算法中选择一种 - 优点
符合开闭原则
避免使用多重条件控制语句
提高算法的保密性和安全性 - 缺点
客户端必须知道所有策略类,并自行决定使用哪一个策略类
产生很多策略类
模板方法模式
-
定义
定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现
模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤 -
适用场景
一次性实现一个算法中不变的部分,并将可变的行为留给子类来实现
各子类中公共的行为被提取出来并集中到一个公共父类中,避免了代码重复 -
优点
提高复用性
提高扩展性
符合开闭原则 -
缺点
类数目增加
增加了系统实现的复杂度
继承关系自身的缺点,如果父类添加新的抽象方法,所有子类都要改一遍 -
扩展
钩子方法
/**课程抽象
* @author MrPeng
* @date 2019/2/16
*/
public abstract class ACourse {
/**
* 制作课程声明为final,不允许子类重写,也就是打乱顺序
*/
protected final void makeCourse(){
this.makePPT();
this.makeVideo();
//写手记作为可选项
if(needWriteArticle()){
this.writeArticle();
}
this.packageCourse();
}
final void makePPT(){
System.out.print("制作PPT---");
}
final void makeVideo(){
System.out.print("制作视频---");
}
final void writeArticle(){
System.out.print("编写手记---");
}
//钩子方法
protected boolean needWriteArticle(){
return false;
}
abstract void packageCourse();
}
--------------------------------------
/**Java课程
* @author MrPeng
* @date 2019/2/16
*/
public class JavaCourse extends ACourse{
@Override
void packageCourse() {
System.out.print("提供Java源代码\n");
}
@Override
protected boolean needWriteArticle() {
return true;
}
}
--------------------------------------------------
/**模板方法模式测试
* @author MrPeng
* @date 2019/2/16
*/
public class Test {
public static void main(String[] args) {
System.out.println("前端课程start---");
ACourse feCourse = new FECourse(true);
feCourse.makeCourse();
System.out.println("前端课程end---");
System.out.println("JAVA课程start---");
ACourse javaCourse = new JavaCourse();
javaCourse.makeCourse();
System.out.println("JAVA课程end---");
}
}
访问者模式
- 定义
封装作用于某数据结构(List,Map)中的各操作
可以在不改变各元素的类的前提下,定义作用这些元素的操作 - 适用场景
一个数据结构如(List/Set/Map等)包含很多类型对象
数据结构与数据操作分离 - 优点
增加新的操作很容易,即增加一个新的访问者 - 缺点
增加新的数据结构困难
具体元素变更比较麻烦
public abstract class Course {
private String name;
//get/set
/**
* 访问方式
*/
public abstract void accept(IVisitor visitor);
}
-----------------------------------
/**免费课程
* @author MrPeng
* @date 2019/2/21
*/
public class FreeCourse extends Course {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
-----------------------------------
/**实战课程-收费
* @author MrPeng
* @date 2019/2/21
*/
public class CodingCourse extends Course{
private int price;
//get/set
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
----------------------------------
/**访问者接口-定义对多个不同对象的访问
* @author MrPeng
* @date 2019/2/21
*/
public interface IVisitor {
void visit(FreeCourse freeCourse);
void visit(CodingCourse codingCourse);
}
-----------------------------------
/**访问者实现访问接口
* @author MrPeng
* @date 2019/2/21
*/
public class Visitor implements IVisitor {
@Override
public void visit(FreeCourse freeCourse) {
System.out.println("免费课程:"+freeCourse.getName());
}
@Override
public void visit(CodingCourse codingCourse) {
System.out.println("实战课程:"+codingCourse.getName() +"价格:"+codingCourse.getPrice());
}
}
---------------------------------
public static void main(String[] args) {
List<Course> courseList = new ArrayList<>();
FreeCourse freeCourse = new FreeCourse();
freeCourse.setName("大话设计模式");
CodingCourse codingCourse = new CodingCourse();
codingCourse.setName("Vue从入门到实战");
codingCourse.setPrice(200);
courseList.add(freeCourse);
courseList.add(codingCourse);
for (Course course : courseList) {
course.accept(new Visitor());
}
}
--------------------------------
免费课程:大话设计模式
实战课程:Vue从入门到实战价格:200
标签:String,void,System,new,设计模式,行为,public,out
From: https://www.cnblogs.com/ranger-dev/p/17435759.html