首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

Java描述设计模式(17):调停者模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 1、场景描述 在公司的日常安排中,通常划分多个部门,每个部门又会分为不同的小组,部门经理的一项核心工作就是协调部门小组之间的工作,例如开发小组,产品小组,小组的需求统一汇总到经理,经理统一安排和协调。 2、场景图解 3、代码实现 public class C01_InScene { public static void main(String[] args) { Manager manager = new Manager() ; EmployeeA employeeA = new EmployeeA("张三",manager) ; EmployeeB employeeB = new EmployeeB("李四",manager) ; employeeA.sendMsg(employeeA.name,"需要产品文档",employeeB); } } /** * 部门协调接口 */ interface Department { void coordinate (String userName,String msg,Employee employee) ; } /** * 部门经理 */ class Manager implements Department { @Override public void coordinate (String userName,String msg,Employee employee) { System.out.println("经理接收【"+userName+"】的协调任务:" + msg); System.out.println("经理转发【"+userName+"】协调任务,@【"+employee.name+"】"); employee.getMsg(userName,msg); } } /** * 员工抽象类 */ abstract class Employee { public String name ; private Department department ; public Employee (String name,Department department){ this.name = name ; this.department = department ; } public void getMsg (String userName,String msg){ System.out.println("【"+this.name+"】收到"+"【"+userName+"】协调任务:["+msg+"]"); } public void sendMsg (String name,String msg,Employee employee){ System.out.println("【"+name+"】发起协调任务:"+ msg); department.coordinate(name,msg,employee); } } /** * 具体员工 */ class EmployeeA extends Employee { public EmployeeA(String name, Department department) { super(name, department); } } class EmployeeB extends Employee { public EmployeeB(String name, Department department) { super(name, department); } } 执行结果 【张三】发起协调任务:需要产品文档 经理接收【张三】的协调任务:需要产品文档 经理转发【张三】协调任务,@【李四】 【李四】收到【张三】协调任务:[需要产品文档] 二、调停者模式 1、基本概念 调停者模式是对象的行为模式。调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互显式引用,通过一个中介对象进行引用通知,从而对象之间解耦。当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的对象间的相互作用。保证这些相互作用可以彼此独立地变化。 2、模式图解 3、核心角色 抽象调停者角色 定义出同事对象到调停者对象的接口,其中主要方法是一个或多个事件方法。 具体调停者角色 实现了抽象调停者所声明的事件方法。具体调停者持有所有的具体同事类,并负责协调各具体同事对象的交互信息。 抽象同事类角色 定义出调停者到同事对象的接口。同事对象只持有调停者而不知道具体的同事对象。 具体同事类角色 所有的具体同事类均从抽象同事类继承而来,需要与其他同事通信的时候,就与持有的调停者通信,调停者会负责与其他的同事对象交互。 4、源码实现 /** * 抽象调停者类 */ interface Mediator { void notify (Colleague colleague); } /** * 抽象同事类 */ abstract class Colleague { /* 持有调停者对象 */ private Mediator mediator; public Colleague(Mediator mediator){ this.mediator = mediator; } public Mediator getMediator(){ return mediator; } } /** * 具体调停者类 */ class ConcreteMediator implements Mediator{ private ConcreteColleagueA colleagueA ; private ConcreteColleagueB colleagueB ; public void setColleagueA(ConcreteColleagueA colleagueA) { this.colleagueA = colleagueA; } public void setColleagueB(ConcreteColleagueB colleagueB) { this.colleagueB = colleagueB; } @Override public void notify(Colleague colleague) { System.out.println("协调通知消息"); } } /** * 具体同事类 */ class ConcreteColleagueA extends Colleague{ public ConcreteColleagueA(Mediator mediator) { super(mediator); } public void operate(){ getMediator().notify(this); } } class ConcreteColleagueB extends Colleague{ public ConcreteColleagueB(Mediator mediator) { super(mediator); } public void operation(){ getMediator().notify(this); } } 三、调停者模式总结 松散耦合 调停者模式通过把多个同事对象之间的交互封装到调停者对象里面,从而使得同事对象之间松散耦合。 集中管理交互 多个同事对象的交互,被封装在调停者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改调停者对象就可以了。 简化对象间关系 没有使用调停者模式的时候,同事对象之间的关系通常是多对多的,引入调停者对象以后,调停者对象和同事对象的关系通常变成双向的一对多。 模式的缺点 调停者模式的一个潜在缺点是,过度集中化,当同事对象很多,交互非常、复杂时,会导致调停者对象变得十分复杂,而且难于管理和维护。 四、源代码地址 GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

优秀的个人博客,低调大师

JAVA设计模式(3)外观模式(门面模式)

2019年阿里云双11活动拼团:https://www.aliyun.com/1111/2019/group-buying-share 针对外观模式,在项目开发和实际运用中十分频繁,但是其极易理解,下面就简要介绍一下。 一、概念介绍 外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。 二、角色及使用场景 简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。 1).门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。 2).子系统角色:实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。 3).客户角色:通过调用Facede来完成要实现的功能。 使用场景: 1- 为复杂的模块或子系统提供外界访问的模块; 2- 子系统相互独立; 3- 在层析结构中,可以使用外观模式定义系统的每一层的入口。 三、实例 下面,我们就通过一个简单的例子来实现该模式。 每个Computer都有CPU、Memory、Disk。在Computer开启和关闭的时候,相应的部件也会开启和关闭,所以,使用了该外观模式后,会使用户和部件之间解耦。如: 包体的创建: 代码实现 首先是子系统类: 【代码清单--1】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * cpu子系统类 7 * @author Administrator 8 * 9 */ 10 public class CPU 11 { 12 public static final Logger LOGGER = Logger.getLogger(CPU.class); 13 public void start() 14 { 15 LOGGER.info("cpu is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("CPU is shutDown..."); 21 } 22 } 【代码清单--2】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * Disk子系统类 7 * @author Administrator 8 * 9 */ 10 public class Disk 11 { 12 public static final Logger LOGGER = Logger.getLogger(Disk.class); 13 public void start() 14 { 15 LOGGER.info("Disk is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("Disk is shutDown..."); 21 } 22 } 【代码清单--3】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * Memory子系统类 7 * @author Administrator 8 * 9 */ 10 public class Memory 11 { 12 public static final Logger LOGGER = Logger.getLogger(Memory.class); 13 public void start() 14 { 15 LOGGER.info("Memory is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("Memory is shutDown..."); 21 } 22 } 然后是,门面类Facade 【代码清单--4】 1 package com.huawei.facadeDesign.facade; 2 3 import org.apache.log4j.Logger; 4 5 import com.huawei.facadeDesign.children.CPU; 6 import com.huawei.facadeDesign.children.Disk; 7 import com.huawei.facadeDesign.children.Memory; 8 9 10 /** 11 * 门面类(核心) 12 * @author Administrator 13 * 14 */ 15 public class Computer 16 { 17 public static final Logger LOGGER = Logger.getLogger(Computer.class); 18 19 private CPU cpu; 20 private Memory memory; 21 private Disk disk; 22 public Computer() 23 { 24 cpu = new CPU(); 25 memory = new Memory(); 26 disk = new Disk(); 27 } 28 public void start() 29 { 30 LOGGER.info("Computer start begin"); 31 cpu.start(); 32 disk.start(); 33 memory.start(); 34 LOGGER.info("Computer start end"); 35 } 36 37 public void shutDown() 38 { 39 LOGGER.info("Computer shutDown begin"); 40 cpu.shutDown(); 41 disk.shutDown(); 42 memory.shutDown(); 43 LOGGER.info("Computer shutDown end..."); 44 } 45 } 最后为,客户角色。 【代码清单--5】 1 package com.huawei.facadeDesign; 2 3 import org.apache.log4j.Logger; 4 5 import com.huawei.facadeDesign.facade.Computer; 6 7 /** 8 * 客户端类 9 * @author Administrator 10 * 11 */ 12 public class Cilent { 13 public static final Logger LOGGER = Logger.getLogger(Cilent.class); 14 public static void main(String[] args) 15 { 16 Computer computer = new Computer(); 17 computer.start(); 18 LOGGER.info("================="); 19 computer.shutDown(); 20 } 21 22 } 【代码清单--6】运行结果 从上面的实例来看,有了这个Facade类,也就是Computer类,用户就不用亲自去调用子系统中的Disk,Memory、CPU类了,不需要知道系统内部的实现细节,甚至都不用知道系统内部的构成。客户端只需要跟Facade交互就可以了。 四、优点 - 松散耦合 使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护; - 简单易用 客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成,它只需要跟Facade类交互即可。 - 更好的划分访问层次 有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,这样就可以实现客户端的使用,很好的隐藏了子系统内部的细节。 五、延伸及应用(补充) ...

优秀的个人博客,低调大师

java设计模式之外观模式(门面模式)

针对外观模式,在项目开发和实际运用中十分频繁,但是其极易理解,下面就简要介绍一下。 一、概念介绍 外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。 二、角色及使用场景 简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。 1).门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。 2).子系统角色:实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。 3).客户角色:通过调用Facede来完成要实现的功能。 使用场景: 1- 为复杂的模块或子系统提供外界访问的模块; 2- 子系统相互独立; 3- 在层析结构中,可以使用外观模式定义系统的每一层的入口。 三、实例 下面,我们就通过一个简单的例子来实现该模式。 每个Computer都有CPU、Memory、Disk。在Computer开启和关闭的时候,相应的部件也会开启和关闭,所以,使用了该外观模式后,会使用户和部件之间解耦。如: 包体的创建: 代码实现 首先是子系统类: 【代码清单--1】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * cpu子系统类 7 * @author Administrator 8 * 9 */ 10 public class CPU 11 { 12 public static final Logger LOGGER = Logger.getLogger(CPU.class); 13 public void start() 14 { 15 LOGGER.info("cpu is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("CPU is shutDown..."); 21 } 22 } 【代码清单--2】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * Disk子系统类 7 * @author Administrator 8 * 9 */ 10 public class Disk 11 { 12 public static final Logger LOGGER = Logger.getLogger(Disk.class); 13 public void start() 14 { 15 LOGGER.info("Disk is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("Disk is shutDown..."); 21 } 22 } 【代码清单--3】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * Memory子系统类 7 * @author Administrator 8 * 9 */ 10 public class Memory 11 { 12 public static final Logger LOGGER = Logger.getLogger(Memory.class); 13 public void start() 14 { 15 LOGGER.info("Memory is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("Memory is shutDown..."); 21 } 22 } 然后是,门面类Facade 【代码清单--4】 1 package com.huawei.facadeDesign.facade; 2 3 import org.apache.log4j.Logger; 4 5 import com.huawei.facadeDesign.children.CPU; 6 import com.huawei.facadeDesign.children.Disk; 7 import com.huawei.facadeDesign.children.Memory; 8 9 10 /** 11 * 门面类(核心) 12 * @author Administrator 13 * 14 */ 15 public class Computer 16 { 17 public static final Logger LOGGER = Logger.getLogger(Computer.class); 18 19 private CPU cpu; 20 private Memory memory; 21 private Disk disk; 22 public Computer() 23 { 24 cpu = new CPU(); 25 memory = new Memory(); 26 disk = new Disk(); 27 } 28 public void start() 29 { 30 LOGGER.info("Computer start begin"); 31 cpu.start(); 32 disk.start(); 33 memory.start(); 34 LOGGER.info("Computer start end"); 35 } 36 37 public void shutDown() 38 { 39 LOGGER.info("Computer shutDown begin"); 40 cpu.shutDown(); 41 disk.shutDown(); 42 memory.shutDown(); 43 LOGGER.info("Computer shutDown end..."); 44 } 45 } 最后为,客户角色。 【代码清单--5】 1 package com.huawei.facadeDesign; 2 3 import org.apache.log4j.Logger; 4 5 import com.huawei.facadeDesign.facade.Computer; 6 7 /** 8 * 客户端类 9 * @author Administrator 10 * 11 */ 12 public class Cilent { 13 public static final Logger LOGGER = Logger.getLogger(Cilent.class); 14 public static void main(String[] args) 15 { 16 Computer computer = new Computer(); 17 computer.start(); 18 LOGGER.info("================="); 19 computer.shutDown(); 20 } 21 22 } 【代码清单--6】运行结果 从上面的实例来看,有了这个Facade类,也就是Computer类,用户就不用亲自去调用子系统中的Disk,Memory、CPU类了,不需要知道系统内部的实现细节,甚至都不用知道系统内部的构成。客户端只需要跟Facade交互就可以了。 四、优点 - 松散耦合 使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护; - 简单易用 客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成,它只需要跟Facade类交互即可。 - 更好的划分访问层次 有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,这样就可以实现客户端的使用,很好的隐藏了子系统内部的细节。 五、延伸及应用(补充) ...

优秀的个人博客,低调大师

MyBatis 3.5.3 发布,Java 数据持久层框架

MyBatis 3.5.3 发布了,MyBatis 的前身即iBatis,是一个数据持久层(ORM)框架。它提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAO)。 版本更新如下: Enhancements 在包含的 <sql /> 的 CDATA 中支持变量替换#1615 在 JDK 14+8 或更高版本上支持默认方法调用#1626 调用默认映射器方法时避免非法的反射访问警告#1636 歧义的 getter/setter 现在仅在实际访问时才抛出 ReflectionException#1201 Bugs SQL provider 引发异常时可能的无限循环#1616 如果下一个元素为 null,则无法迭代 Cursor#1653 queryCursor() 在 MySQL Connector/J 的流模式下失败#1654 发布公告:https://blog.mybatis.org/2019/10/mybatis-353-released.html

优秀的个人博客,低调大师

Java描述设计模式(14):解释器模式

本文源码:GitHub·点这里 || GitEE·点这里 一、解释器模式 1、基础概念 解释器模式是对象的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的表达式。 2、模式图解 3、核心角色 (1)、抽象表达式 Express:声明具体表达式角色需要实现的抽象接口,该接口主要提供一个interpret()方法,称做解释操作。 (2)、终结符表达式 TerminalExpress:实现抽象表达式角色接口,主要是一个interpret()方法;每个终结符都有一个具体终结表达式与之相对应。比如解析c=a+b,a和b是终结符,解析a和b的解释器就是终结符表达式。 (3)、非终结符表达式 NotTerminalExpress:每一条规则都需要一个具体的非终结符表达式用来衔接,一般是指运算符或者逻辑判断,比如c=a+b,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。 (4)、环境容器 DataMap:一般是用来存放各个终结符所对应的具体值,比如c=a+b转换为c=1+2。这些信息需要一个存放环境。 4、源代码实现 类图结构 源码实现 public class C01_InScene { public static void main(String[] args) { DataMap dataMap = new DataMap(); TerminalExpress terminalExpress1 = new TerminalExpress("num1"); TerminalExpress terminalExpress2 = new TerminalExpress("num2"); TerminalExpress terminalExpress3 = new TerminalExpress("num3"); dataMap.putData(terminalExpress1, 1); dataMap.putData(terminalExpress2, 2); dataMap.putData(terminalExpress3, 3); // 1+2-3 = 0 System.out.println(new Minus( new Add(terminalExpress1,terminalExpress2), terminalExpress3) .interpret(dataMap)); } } // 解释器接口 interface Express { Integer interpret(DataMap dataMap) ; } // 非终结符表达式 abstract class NotTerminalExpress implements Express { Express express1,express2; public NotTerminalExpress(Express express1, Express express2){ this.express1 = express1; this.express2 = express2; } } // 终结符表达式: 1+2 终结符: 1 和 2 class TerminalExpress implements Express { public String field ; public TerminalExpress (String field){ this.field = field ; } @Override public Integer interpret(DataMap dataMap) { return dataMap.getData(this); } } // 加法表达式 class Add extends NotTerminalExpress { public Add (Express e1, Express e2) { super(e1, e2); } // 将两个表达式相减 @Override public Integer interpret(DataMap context) { return this.express1.interpret(context) + this.express2.interpret(context); } } // 减法表达式 class Minus extends NotTerminalExpress { public Minus (Express e1, Express e2) { super(e1, e2); } // 将两个表达式相减 @Override public Integer interpret(DataMap context) { return this.express1.interpret(context) - this.express2.interpret(context); } } // 数据容器 class DataMap { private Map<Express,Integer> dataMap = new HashMap<>() ; public void putData (Express key,Integer value){ dataMap.put(key,value) ; } public Integer getData (Express key){ return dataMap.get(key) ; } } 二、Spring框架应用 1、源码案例 import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; public class SpringTest { public static void main(String[] args) { SpelExpressionParser parser = new SpelExpressionParser () ; Expression expression = parser.parseExpression("(1+3-2)*3") ; Integer result = (Integer)expression.getValue() ; System.out.println("result="+result); } } 2、代码分析 (1)Expression结构 表达式接口:具有不同的实现类。 interface Expression class CompositeStringExpression implements Expression class LiteralExpression implements Expression class SpelExpression implements Expression 核心方法: Object getValue() throws EvaluationException; (2)SpelExpressionParser结构 SpelExpressionParser extends TemplateAwareExpressionParser TemplateAwareExpressionParser implements ExpressionParser interface ExpressionParser (3)ExpressionParser接口 public interface ExpressionParser { Expression parseExpression(String var1) ; Expression parseExpression(String var1, ParserContext var2) ; } (4)Expression获取 根据不同的条件获取不同的Expression对象。这里产生类的依赖关系。 源码位置:TemplateAwareExpressionParser public Expression parseExpression(String expressionString, ParserContext context) throws ParseException { if (context == null) { context = NON_TEMPLATE_PARSER_CONTEXT; } return context.isTemplate() ? this.parseTemplate(expressionString, context) : this.doParseExpression(expressionString, context); } 三、模式总结 场景 编译器、运算符表达式、正则表达式、机器人等。 优点 当有一个表达式或者语言需要解释执行,该场景下的内容可以考虑使用解释器模式,使程序具有良好的扩展性。 缺点 解释器模式会引起类膨胀,会导致程序执行和调试非常复杂,不容易理解。 四、源代码地址 GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册