您的位置:首页 > 教育 > 培训 > 高新营销型网站建设公司_建设通网站上能查到的企业_app001推广平台官网_中山谷歌推广

高新营销型网站建设公司_建设通网站上能查到的企业_app001推广平台官网_中山谷歌推广

2024/10/7 9:00:18 来源:https://blog.csdn.net/m0_66825548/article/details/142642910  浏览:    关键词:高新营销型网站建设公司_建设通网站上能查到的企业_app001推广平台官网_中山谷歌推广
高新营销型网站建设公司_建设通网站上能查到的企业_app001推广平台官网_中山谷歌推广

在这里插入图片描述

哈喽,各位盆友们!我是你们亲爱的学徒小z,今天给大家分享一篇有关设计模式的文章,希望可以帮助到大家。

文章目录

  • 定义
  • 样例介绍
    • 1.类简介
    • 2.具体代码
  • 通用类图
    • 1.通用类介绍
    • 2.通用代码
    • 3.实际应用
    • 4.优点
    • 5.缺点
  • 使用场景
  • 撤销问题


定义

  • 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请 求排队或者记录请求日志,可以提供命令的撤销和恢复功能
  • 命令模式是一种行为型设计模式(行为型设计模式:它主要关注对象之间的交互和职责分配,用于处理系统中对象的行为)

样例介绍

我们先来看一个项目和甲方客户之间的样例

图一

图二
在这里插入图片描述

  • 图一是未修改的类图,可以发现,客户(client)每次提新的需求都要和对应的组进行沟通CodeGroup、PageGroup、RequirementGroup。这样一开始客户可能觉得没什么,但事件一长,是个人都烦,并且各个组也会感觉难受。所以客户提出需求:你们给我派一个负责人来和我沟通,我将需求给他说,只要最终实现了就行。于是就出现了Invoker来听取客户的需求,于是Invoker接受客户的string类型命令,等等…,string类型,看起来不太好,客户命令是string类型的,这有非常多的变化,而且没有约束力。我们想办法解决这个问题,就产生了对命令的封装类Command(抽象类),DeletePageCommand、AddRequirementCommand(具体实现类,有N个命令就有N个实现类)。

1.类简介

  • Command抽象类:客户发给我们的命令,定义三个工作组的成员变量,供子类使用; 定义一个抽象方法execute,由子类来实现

    Command抽象类可以有N个子类,如增加一个功能命令(AddFunCommand),删除一份需求命令(DeleteRequirementCommand)等,这里就不再描述了,只要是由客户产生、时常性的行为都可以定义为一个命令,其实现类都比较简单

  • CInvoker实现类:项目接头负责人,setComand接收客户发给我们的命令,action方法是执行客户的命令(方法名写成是action,与command的execute区分开,避免混淆)

2.具体代码

public abstract class Command {//把三个组都定义好,子类可以直接使用protected RequirementGroup rg = new RequirementGroup(); //需求组protected PageGroup pg = new PageGroup(); //美工组protected CodeGroup cg = new CodeGroup(); //代码组//只有一个方法,你要我做什么事情public abstract void execute();
}//增加需求的命令
public class AddRequirementCommand extends Command {//执行增加一项需求的命令public void execute() {//找到需求组super.rg.find();//增加一份需求super.rg.add();//给出计划super.rg.plan();}
}//删除页面的命令
public class DeletePageCommand extends Command {//执行删除一个页面的命令public void execute() {//找到页面组super.pg.find();//删除一个页面super.rg.delete();//给出计划super.rg.plan();}
}//负责人
public class Invoker {//什么命令private Command command;//客户发出命令public void setCommand(Command command){this.command = command;}//执行客户的命令public void action(){this.command.execute();}
}//增加一项需求,如果客户要删除一个页面,修改有多大?
public class Client {public static void main(String[] args) {//定义我们的接头人Invoker xiaoSan = new Invoker(); //接头人就是小三//客户要求增加一项需求System.out.println("------------客户要求增加一项需求---------------");//客户给我们下命令来Command command = new AddRequirementCommand();//Command command = new DeletePageCommand();//接头人接收到命令xiaoSan.setCommand(command);//接头人执行命令xiaoSan.action();}
}

通用类图

在这里插入图片描述

1.通用类介绍

  • Receiver:该角色是干活的角色,命令传递到这里是应该被执行的,具体到我们上面的例子中就是Group的三个实现类

  • Command命令角色:需要执行的所有命令都在这里声明

  • Invoker调用者角色:接收到命令,并执行命令。

  • 命令模式比较简单,但是在项目中非常频繁地使用,因为它的封装性非常好,把请求方 (Invoker)和执行方(Receiver)分开了,扩展性也有很好的保障,通用代码比较简单

2.通用代码

//通用Receiver类,为什么Receiver是一个抽象类?那是因为接收者可以有多个,有多个就需要定
//义一个所有特性的抽象集合——抽象的接收者
public abstract class Receiver {//抽象接收者,定义每个接收者都必须完成的业务public abstract void doSomething();
}//具体的Receiver类
public class ConcreteReciver1 extends Receiver{//每个接收者都必须处理一定的业务逻辑public void doSomething(){}
}public class ConcreteReciver2 extends Receiver{//每个接收者都必须处理一定的业务逻辑public void doSomething(){}
}//抽象的Command类
public abstract class Command {//每个命令类都必须有一个执行命令的方法public abstract void execute();
}//具体的Command类
public class ConcreteCommand1 extends Command {//对哪个Receiver类进行命令处理//这里可以移到抽象类中中,private Receiver receiver;//构造函数传递接收者public ConcreteCommand1(Receiver _receiver){this.receiver = _receiver;}//必须实现一个命令public void execute() {//业务处理this.receiver.doSomething();}
}
//ConcreteCommand2类似//调用者Invoker类
public class Invoker {private Command command;public void setCommand(Command _command){this.command = _command;}//执行命令public void action(){this.command.execute();}
}public class Client {public static void main(String[] args) {//首先声明调用者InvokerInvoker invoker = new Invoker();//定义接收者Receiver receiver = new ConcreteReciver1();//定义一个发送给接收者的命令Command command = new ConcreteCommand1(receiver);//把命令交给调用者去执行invoker.setCommand(command);invoker.action();}
}

3.实际应用

​ 每一个模式到实际应用的 时候都有一些变形,命令模式的Receiver在实际应用中一般都会被封装掉(除非非常必要, 例如撤销处理),那是因为在项目中:约定的优先级最高,每一个命令是对一个或多个 Receiver的封装,我们可以在项目中通过有意义的类名或命令名处理命令角色和接收者角色 的耦合关系(这就是约定),减少高层模块(Client类)对低层模块(Receiver角色类)的依赖关系,提高系统整体的稳定性。因此,建议大家在实际的项目开发时采用封闭Receiver的方式,减少Client对Reciver的依赖,

//修改如下
//完美的Command类
public abstract class Command {//定义一个子类的全局共享变量,这里是修改的地方protected final Receiver receiver;//实现类必须定义一个接收者public Command(Receiver _receiver){this.receiver = _receiver;}//每个命令类都必须有一个执行命令的方法public abstract void execute();
}//具体的命令
public class ConcreteCommand1 extends Command {//声明自己的默认接收者public ConcreteCommand1(){super(new ConcreteReciver1());}//设置新的接收者public ConcreteCommand1(Receiver _receiver){super(_receiver);}//每个具体的命令都必须实现一个命令public void execute() {//业务处理super.receiver.doSomething();}
}// 场景类,高层次的模块不需要知道接收者
public class Client {public static void main(String[] args) {//首先声明调用者InvokerInvoker invoker = new Invoker();//定义一个发送给接收者的命令Command command = new ConcreteCommand1();//把命令交给调用者去执行invoker.setCommand(command);invoker.action();}
}

4.优点

  • 类间解耦
  • 可扩展性
  • 命令模式结合其他模式更好用。结合责任链模式,实现命令族解析任务;结合模板方法,减少子类膨胀问题。

5.缺点

  • 有N个命令,子类膨胀非常大

使用场景

  • 解决在软件系统中请求者和执行者之间的紧耦合问题,特别是在需要对行为进行记录、撤销/重做或事务处理等场景。

撤销问题

  • 发出一个命令,执行后撤回(执行后撤回是状态变更)如何实现

    //修改后的Group类
    public abstract class Group {//甲乙双方分开办公,你要和那个组讨论,你首先要找到这个组public abstract void find();//被要求增加功能public abstract void add();//被要求删除功能public abstract void delete();//被要求修改功能public abstract void change();//被要求给出所有的变更计划public abstract void plan();//每个接收者都要对直接执行的任务可以回滚public void rollBack(){//根据日志进行回滚}
    }/*仅仅增加了一个rollBack的方法,每个接收者都可以对自己实现的任务进行回滚。怎么
    回滚?根据事务日志进行回滚!新增加的一个命令CancelDeletePageCommand实现撤销刚刚
    发出的删除命令*/
    // 撤销命令
    public class CancelDeletePageCommand extends Command {//撤销删除一个页面的命令public void execute() {super.pg.rollBack();}
    }

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com