首页 文章 精选 留言 我的

精选列表

搜索[数据库设计],共10000篇文章
优秀的个人博客,低调大师

Java描述设计模式(22):策略模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 每年双十一,各大电商平台会推出不同的满减策略,当用户的消费金额满一定额度后,会进行减去一定的优惠额度,从而来一波清仓甩卖,使用策略模式来描述该流程。 public class C01_InScene { public static void main(String[] args) { // 选择满减策略,走相应的计算方式 FullReduce strategy = new Full100 (); Payment price = new Payment(strategy); double quote = price.payment(300); System.out.println("最终价格为:" + quote); } } /** * 付款 */ class Payment { private FullReduce fullReduce ; public Payment (FullReduce fullReduce){ this.fullReduce = fullReduce ; } public double payment (double totalPrice){ return this.fullReduce.getPayMoney(totalPrice) ; } } /** * 金额满减接口 */ interface FullReduce { double getPayMoney (double totalPrice) ; } /** * 不同的满减策略 */ class Full100 implements FullReduce { @Override public double getPayMoney(double totalPrice) { if (totalPrice >= 100){ totalPrice = totalPrice-20.0 ; } return totalPrice ; } } class Full500 implements FullReduce { @Override public double getPayMoney(double totalPrice) { if (totalPrice >= 500){ totalPrice = totalPrice-120.0 ; } return totalPrice ; } } 二、策略模式 1、基础概念 策略模式属于对象的行为模式。策略模式中定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客 户端。 2、模式图解 3、核心角色 环境角色 持有一个Strategy策略接口角色的引用。 抽象策略角色 通常由一个接口或抽象类实现。此角色给出所有的具体策略类要实现的接口。 具体策略角色 包装相关的算法或业务流程。 4、源码实现 public class C02_Strategy { public static void main(String[] args) { Strategy strategy = new ConcreteStrategyB() ; Context context = new Context(strategy) ; context.userMethod(); } } /** 环境角色类 */ class Context { //持有一个具体策略的对象 private Strategy strategy; /** * 构造函数,传入一个具体策略对象 * @param strategy 具体策略对象 */ public Context(Strategy strategy){ this.strategy = strategy; } public void userMethod (){ this.strategy.strategyMethod(); } } /** 抽象策略类 */ interface Strategy { // 策略方法 void strategyMethod () ; } /** 具体策略类 */ class ConcreteStrategyA implements Strategy { @Override public void strategyMethod() { System.out.println("策略A方法"); } } class ConcreteStrategyB implements Strategy { @Override public void strategyMethod() { System.out.println("策略B方法"); } } 三、策略模式总结 策略模式的关键是:变化的与不变分离,体现了“对修改关闭,对扩展开放”原则。客户端增加行为不用修改原有代码,只要添加一种策略即可,易于切换、易于理解、易于扩展。策略过多是会导致类数目庞大,变得难以维护。 四、源代码地址 GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

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

Java描述设计模式(21):状态模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 1、场景描述 变色龙是爬行动物,是非常奇特的动物,它有适于树栖生活的种种特征和行为,身体也会随着环境的变化而变化出适应环境的颜色,非常神奇。下面基于状态模式对该变化过程进行描述。 2、代码实现 public class C01_InScene { public static void main(String[] args) { Chameleon chameleon = new Chameleon("红色","花丛环境") ; LifeContext lifeContext = new LifeContext() ; // 树叶环境 BodyColor bodyColor = new GreenColor (); lifeContext.setBodyColor(bodyColor); lifeContext.change(chameleon); // 树枝环境 bodyColor = new GrayColor() ; lifeContext.setBodyColor(bodyColor); lifeContext.change(chameleon); } } /** * 变色龙 */ class Chameleon { public String color ; public String contextDesc ; public Chameleon(String color, String contextDesc) { this.color = color; this.contextDesc = contextDesc; } } /** * 变色龙生存环境 */ class LifeContext { private BodyColor bodyColor; public void setBodyColor(BodyColor bodyColor) { this.bodyColor = bodyColor; } public void change (Chameleon chameleon){ bodyColor.change(chameleon) ; } } /** * 变色龙身体颜色抽象类 */ interface BodyColor { void change (Chameleon chameleon); } /** * 变色龙身体颜色具体类 */ class GreenColor implements BodyColor { @Override public void change(Chameleon chameleon) { System.out.println("变化前:"+chameleon.color+";"+chameleon.contextDesc); chameleon.contextDesc = "树叶环境" ; chameleon.color = "绿色" ; System.out.println("变化后:"+chameleon.color+";"+chameleon.contextDesc); } } class GrayColor implements BodyColor { @Override public void change(Chameleon chameleon) { System.out.println("变化前:"+chameleon.color+";"+chameleon.contextDesc); chameleon.contextDesc = "树枝环境" ; chameleon.color = "灰色" ; System.out.println("变化后:"+chameleon.color+";"+chameleon.contextDesc); } } 二、状态模式 1、基础概念 状态模式是对象的行为模式,状态模式允许一个对象在其内部状态改变的时候改变其行为。状态模式把对象的行为封装在不同状态的对象中,每一个状态对象都是抽象状态类的子类。意图是让一个对象在其内部状态改变的时候,其行为也随之改变。 2、模式图解 3、核心角色 环境角色 持有具体状态类的对象实例。这个具体状态类的实例给出此环境对象的现有状态。 抽象状态角色 定义一个接口,封装环境对象的状态所对应的行为。 具体状态角色 具体状态类实现了环境的状态所对应的行为。 4、源码实现 public class C02_State { public static void main(String[] args){ Context context = new Context(); State state = new ConcreteStateA() ; context.setState(state); context.printInfo("当前环境状态A"); state = new ConcreteStateB(); context.setState(state); context.printInfo("当前环境状态B"); } } /** * 环境角色 */ class Context { private State state; public void setState(State state) { this.state = state; } public void printInfo (String info) { state.stateInfo(info); } } /** * 抽象状态角色 */ interface State { void stateInfo (String param); } /** * 具体状态角色 */ class ConcreteStateA implements State { @Override public void stateInfo (String info) { System.out.println("ConcreteStateA:" + info); } } class ConcreteStateB implements State { @Override public void stateInfo (String info) { System.out.println("ConcreteStateB:" + info); } } 三、模式总结 将容易产生问题的if-else语句拆分,状态模式将每个状态的行为封装到对应的一个类中,代码有很强的可读性。 符合“开闭原则”,容易增删操作,管理状态。 会存在很多状态时。每个状态都要一个对应的类,会产生很多类,增加维护难度。 应用场景:当一个事件或者对象有很多种状态,状态之间会相互转换,不同的状态有不同的行为,可以考虑使用状态模式。 四、源代码地址 GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

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

Java描述设计模式(20):命令模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 1、场景描述 智能电脑的品牌越来越多,由此诞生了一款电脑控制的APP,万能遥控器,用户在使用遥控器的时候,可以切换为自家电视的品牌,然后对电视进行控制。 2、代码实现 public class C01_InScene { public static void main(String[] args) { TVClient tvClient = new TVClient() ; Remote remote = new RemoteApp(tvClient) ; UserClient userClient = new UserClient(remote) ; userClient.action("HM","换台"); } } /** * 遥控接口 */ interface Remote { void controlTV (String tvType,String task); } /** * 遥控器APP */ class RemoteApp implements Remote { private TVClient tvClient = null ; public RemoteApp (TVClient tvClient){ this.tvClient = tvClient ; } @Override public void controlTV(String tvType, String task) { tvClient.action(tvType,task); } } /** * 用户端 */ class UserClient { // 持有遥控器 private Remote remote = null ; public UserClient (Remote remote){ this.remote = remote ; } public void action (String tvType, String task){ remote.controlTV(tvType,task); } } /** * 电视端 */ class TVClient { public void action (String tvType, String task){ System.out.println("TV品牌:"+tvType+";执行:"+task); } } 二、命令模式 1、基础概念 命令模式属于对象的行为模式。命令模式把一个请求或者操作封装到一个对象中。把发出命令的动作和执行命令的动作分割开,委派给不同的对象。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行。 2、模式图解 3、核心角色 命令角色 声明所有具体命令类的抽象接口。 具体命令角色 定义接收者和行为之间的交互方式:实现execute()方法,调用接收者的相应操作 , 传递命令信息。 请求者角色 负责调用命令对象执行请求,相关的方法叫做行动方法。 接收者角色 执行请求。任何一个类都可以成为接收者,执行请求的方法叫做行动方法。 4、源码实现 public class C02_Command { public static void main(String[] args) { Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); Invoker invoker = new Invoker(command); invoker.action("卧倒"); } } /** * 命令角色 */ interface Command { // 执行方法 void execute(String task); } /** * 具体命令角色类 */ class ConcreteCommand implements Command { //持有相应的接收者对象 private Receiver receiver = null; public ConcreteCommand(Receiver receiver){ this.receiver = receiver; } @Override public void execute(String task) { //接收方来真正执行请求 receiver.action(task); } } /** * 请求者角色类 */ class Invoker { // 持有命令对象 private Command command = null; public Invoker(Command command){ this.command = command; } // 行动方法 public void action(String task){ command.execute(task); } } /** * 接收者角色类 */ class Receiver { // 执行命令操作 public void action(String task){ System.out.println("执行命令:"+task); } } 三、Spring框架应用 Spring框架中封装的JdbcTemplate类API使用到了命令模式。 1、JdbcOperations接口 public interface JdbcOperations { @Nullable <T> T execute(StatementCallback<T> var1) ; } 2、JdbcTemplate类 这里只保留模式方法的代码。 public class JdbcTemplate implements JdbcOperations { @Nullable public <T> T execute(StatementCallback<T> action) { try { T result = action.doInStatement(stmt); } catch (SQLException var9) { } finally { } } } 3、StatementCallback接口 @FunctionalInterface public interface StatementCallback<T> { @Nullable T doInStatement(Statement var1) ; } 四、命令模式总结 松散的耦合 命令模式使得命令发起者和命令执行者解耦,发起命令的对象完全不知道具体实现对象是谁。这和常见的MQ消息队列原理是类似的。 动态的控制 命令模式把请求封装起来,可以动态地对它进行参数化、队列化和等操作和管理,使系统更加的灵活。 良好的扩展性 命令发起者和命令执行者实现完全解耦,因此扩展添加新命令很容易。 五、源代码地址 GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

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

Java设计模式之责任链模式

2019年阿里云双11活动拼团:https://www.aliyun.com/1111/2019/group-buying-share 生产一个产品,需要依次执行多个步骤,才能完成,那么是使用责任链模式则是极好的。 在性能告警模块开发过程中,创建一条告警规则需要执行阈值解析,中间表生成,流任务生成,规则入库,告警事件入库等诸多操作。如果把这些步骤糅合在一个类中,代码可读性及复杂度往往是灾难的,特别对于这么多步骤的事务性操作,更是力不从心。使用责任链模式,上述问题迎刃而解。 以告警规则创建为例子,简化流程如下 阈值解析 ---> 流任务生成 ---> 规则入库 回滚流程如下 1、 阈值解析失败:回滚阈值解析。 2、 流任务生产失败:回滚流任务生成,阈值解析。 3、 规则入库失败:回滚规则入库,流任务生成,阈值解析。 采用责任链模式编码,思路如下: 1、 编写阈值解析处理器,流任务生成处理器,规则入库处理器,每个处理器包含业务处理方法和回滚方法; 2、 一个处理器业务代码执行完成后主动调用下一个处理器业务方法; 3、 一个处理器业务代码执行失败主动调用本处理器回滚方法,本处理器回滚完成后主动调用上一个处理器回滚方法。 代码如下 1、 抽象处理器 package com.coshaho.learn.handler; /** * * AbstractRuleHandler.java Create on 2017年5月5日 下午11:20:15 * * 类功能说明: 告警规则责任链处理节点抽象类 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public abstract class AbstractRuleHandler { // 上一个处理器 private AbstractRuleHandler preHandler; // 下一个处理器 private AbstractRuleHandler nextHandler; /** * 业务执行 * * @author coshaho * @param rule */ public void doHandle(AlarmRule rule) { try { doHandleReal(rule); } catch(Exception e) { // 业务代码执行失败主动回滚 rollBack(rule); return; } // 业务代码执行成功主动调用下一个处理器处理 if(null != nextHandler) { nextHandler.doHandle(rule); } } /** * 事务回滚 * * @author coshaho * @param rule */ public void rollBack(AlarmRule rule) { rollBackReal(rule); // 本处理器业务回滚完成,主动调用前一个处理器业务回滚 if(null != preHandler) { preHandler.rollBack(rule); } } /** * 每个处理器特有的业务处理方法 * * @author coshaho * @param rule * @throws Exception */ public abstract void doHandleReal(AlarmRule rule) throws Exception; /** * 每个处理器特有的业务回滚方法 * * @author coshaho * @param rule */ public abstract void rollBackReal(AlarmRule rule); private AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler) { this.preHandler = preHandler; return preHandler; } public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler) { this.nextHandler = nextHandler; nextHandler.setPreHandler(this); return nextHandler; } } 2、阈值解析处理器 package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * ThresholdParseHandler.java Create on 2017年5月5日 下午11:41:20 * * 类功能说明: 阈值解析 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class ThresholdParseHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getThreshold())) { throw new Exception("Threshold is empty."); } System.out.println("Parse threshold success. Threshold is " + rule.getThreshold()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll parse threshold. Threshold is " + rule.getThreshold()); } } 3、流任务生成处理器 package com.coshaho.learn.handler; /** * * StreamGenerateHandler.java Create on 2017年5月5日 下午11:41:43 * * 类功能说明: 告警流规则生成 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class StreamGenerateHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { System.out.println("Generate stream success."); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll Generate stream."); } } 4、规则入库处理器 package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08 * * 类功能说明: 告警规则持久化 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class RulePesistHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getName())) { throw new Exception("Rule name is empty."); } System.out.println("Persist rule success. Rule name is " + rule.getName()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll persist rule. Rule name is " + rule.getName()); } } 5、规则入库处理器 package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08 * * 类功能说明: 告警规则持久化 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class RulePesistHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getName())) { throw new Exception("Rule name is empty."); } System.out.println("Persist rule success. Rule name is " + rule.getName()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll persist rule. Rule name is " + rule.getName()); } } 6、告警规则 package com.coshaho.learn.handler; /** * * AlarmRule.java Create on 2017年5月5日 下午11:40:50 * * 类功能说明: 告警规则 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class AlarmRule { private String name; private String type; private String threshold; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getThreshold() { return threshold; } public void setThreshold(String threshold) { this.threshold = threshold; } } 7、规则创建责任链 package com.coshaho.learn.handler; /** * * AlarmRuleCreator.java Create on 2017年5月5日 下午11:56:45 * * 类功能说明: 告警规则创建 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class AlarmRuleCreator { private AbstractRuleHandler alarmRuleHandler; public AlarmRuleCreator() { alarmRuleHandler = new ThresholdParseHandler(); alarmRuleHandler.setNextHandler(new StreamGenerateHandler()) .setNextHandler(new RulePesistHandler()); } public void create(AlarmRule rule) { alarmRuleHandler.doHandle(rule); } public static void main(String[] args) { AlarmRule rule = new AlarmRule(); rule.setThreshold("cpuRate < 10"); rule.setName("Cpu Alarm"); AlarmRuleCreator ruleCreator = new AlarmRuleCreator(); ruleCreator.create(rule); System.out.println(); rule.setName(""); ruleCreator.create(rule); } } 测试结果 Parse threshold success. Threshold is cpuRate < 10 Generate stream success. Persist rule success. Rule name is Cpu Alarm Parse threshold success. Threshold is cpuRate < 10 Generate stream success. Roll persist rule. Rule name is Roll Generate stream. Roll parse threshold. Threshold is cpuRate < 10

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

JAVA设计模式(2)建造者模式

1 定义 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 类型:创建类模式。 四个要素: 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。 建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。 导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。 2 代码实现 class Product { private String name; private String type; public void showProduct(){ System.out.println(“名称:”+name); System.out.println(“型号:”+type); } public void setName(String name) { this.name = name; } public void setType(String type) { this.type = type; } } abstract class Builder { public abstract void setPart(String arg1, String arg2); public abstract Product getProduct(); } class ConcreteBuilder extends Builder { private Product product = new Product(); public Product getProduct() { return product; } public void setPart(String arg1, String arg2) { product.setName(arg1); product.setType(arg2); } } public class Director { private Builder builder = new ConcreteBuilder(); public Product getAProduct(){ builder.setPart(“宝马汽车”,“X7”); return builder.getProduct(); } public Product getBProduct(){ builder.setPart(“奥迪汽车”,“Q5”); return builder.getProduct(); } } public class Client { public static void main(String[] args){ Director director = new Director(); Product product1 = director.getAProduct(); product1.showProduct(); Product product2 = director.getBProduct(); product2.showProduct(); } } 3 比较及总结 建造者模式的优点: 首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。 其次,建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。 建造者模式与工厂模式的区别: 建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了一个“导演类”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。 与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。 总结: 建造者模式与工厂模式类似,他们都是建造者模式,适用的场景也很相似。一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式

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

Java设计模式应用_责任链模式

生产一个产品,需要依次执行多个步骤,才能完成,那么是使用责任链模式则是极好的。 在性能告警模块开发过程中,创建一条告警规则需要执行阈值解析,中间表生成,流任务生成,规则入库,告警事件入库等诸多操作。如果把这些步骤糅合在一个类中,代码可读性及复杂度往往是灾难的,特别对于这么多步骤的事务性操作,更是力不从心。使用责任链模式,上述问题迎刃而解。 以告警规则创建为例子,简化流程如下 阈值解析 ---> 流任务生成 ---> 规则入库 回滚流程如下 1、 阈值解析失败:回滚阈值解析。 2、 流任务生产失败:回滚流任务生成,阈值解析。 3、 规则入库失败:回滚规则入库,流任务生成,阈值解析。 采用责任链模式编码,思路如下: 1、 编写阈值解析处理器,流任务生成处理器,规则入库处理器,每个处理器包含业务处理方法和回滚方法; 2、 一个处理器业务代码执行完成后主动调用下一个处理器业务方法; 3、 一个处理器业务代码执行失败主动调用本处理器回滚方法,本处理器回滚完成后主动调用上一个处理器回滚方法。 代码如下 1、 抽象处理器 package com.coshaho.learn.handler; /** * * AbstractRuleHandler.java Create on 2017年5月5日 下午11:20:15 * * 类功能说明: 告警规则责任链处理节点抽象类 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public abstract class AbstractRuleHandler { // 上一个处理器 private AbstractRuleHandler preHandler; // 下一个处理器 private AbstractRuleHandler nextHandler; /** * 业务执行 * * @author coshaho * @param rule */ public void doHandle(AlarmRule rule) { try { doHandleReal(rule); } catch(Exception e) { // 业务代码执行失败主动回滚 rollBack(rule); return; } // 业务代码执行成功主动调用下一个处理器处理 if(null != nextHandler) { nextHandler.doHandle(rule); } } /** * 事务回滚 * * @author coshaho * @param rule */ public void rollBack(AlarmRule rule) { rollBackReal(rule); // 本处理器业务回滚完成,主动调用前一个处理器业务回滚 if(null != preHandler) { preHandler.rollBack(rule); } } /** * 每个处理器特有的业务处理方法 * * @author coshaho * @param rule * @throws Exception */ public abstract void doHandleReal(AlarmRule rule) throws Exception; /** * 每个处理器特有的业务回滚方法 * * @author coshaho * @param rule */ public abstract void rollBackReal(AlarmRule rule); private AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler) { this.preHandler = preHandler; return preHandler; } public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler) { this.nextHandler = nextHandler; nextHandler.setPreHandler(this); return nextHandler; } } 2、阈值解析处理器 package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * ThresholdParseHandler.java Create on 2017年5月5日 下午11:41:20 * * 类功能说明: 阈值解析 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class ThresholdParseHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getThreshold())) { throw new Exception("Threshold is empty."); } System.out.println("Parse threshold success. Threshold is " + rule.getThreshold()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll parse threshold. Threshold is " + rule.getThreshold()); } } 3、流任务生成处理器 package com.coshaho.learn.handler; /** * * StreamGenerateHandler.java Create on 2017年5月5日 下午11:41:43 * * 类功能说明: 告警流规则生成 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class StreamGenerateHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { System.out.println("Generate stream success."); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll Generate stream."); } } 4、规则入库处理器 package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08 * * 类功能说明: 告警规则持久化 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class RulePesistHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getName())) { throw new Exception("Rule name is empty."); } System.out.println("Persist rule success. Rule name is " + rule.getName()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll persist rule. Rule name is " + rule.getName()); } } 5、规则入库处理器 package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08 * * 类功能说明: 告警规则持久化 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class RulePesistHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getName())) { throw new Exception("Rule name is empty."); } System.out.println("Persist rule success. Rule name is " + rule.getName()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll persist rule. Rule name is " + rule.getName()); } } 6、告警规则 package com.coshaho.learn.handler; /** * * AlarmRule.java Create on 2017年5月5日 下午11:40:50 * * 类功能说明: 告警规则 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class AlarmRule { private String name; private String type; private String threshold; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getThreshold() { return threshold; } public void setThreshold(String threshold) { this.threshold = threshold; } } 7、规则创建责任链 package com.coshaho.learn.handler; /** * * AlarmRuleCreator.java Create on 2017年5月5日 下午11:56:45 * * 类功能说明: 告警规则创建 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class AlarmRuleCreator { private AbstractRuleHandler alarmRuleHandler; public AlarmRuleCreator() { alarmRuleHandler = new ThresholdParseHandler(); alarmRuleHandler.setNextHandler(new StreamGenerateHandler()) .setNextHandler(new RulePesistHandler()); } public void create(AlarmRule rule) { alarmRuleHandler.doHandle(rule); } public static void main(String[] args) { AlarmRule rule = new AlarmRule(); rule.setThreshold("cpuRate < 10"); rule.setName("Cpu Alarm"); AlarmRuleCreator ruleCreator = new AlarmRuleCreator(); ruleCreator.create(rule); System.out.println(); rule.setName(""); ruleCreator.create(rule); } } 测试结果 Parse threshold success. Threshold is cpuRate < 10 Generate stream success. Persist rule success. Rule name is Cpu Alarm Parse threshold success. Threshold is cpuRate < 10 Generate stream success. Roll persist rule. Rule name is Roll Generate stream. Roll parse threshold. Threshold is cpuRate < 10

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

Java设计模式系列-享元模式

​ 一、概述 享元模式:“享”就是分享之意,指一物被众人共享,而这也正是该模式的终旨所在。 享元模式有点类似于单例模式,都是只生成一个对象来被共享使用。这里有个问题,那就是对共享对象的修改,为了避免出现这种情况,我们将这些对象的公共部分,或者说是不变化的部分抽取出来形成一个对象。这个对象就可以避免到修改的问题。 享元的目的是为了减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。 二、示例 下面我们来看一个简单的例子: 建筑接口:JianZhu public interface Jianzhu { void use(); } 体育馆实现类:TiYuGuan public class TiYuGuan implements Jianzhu { private String name; private String shape; private String yundong; public TiYuGuan(String yundong){ this.setYundong(yundong); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getShape() { return shape; } public void setShape(String shape) { this.shape = shape; } public String getYundong() { return yundong; } public void setYundong(String yundong) { this.yundong = yundong; } @Override public void use() { System.out.println("该体育馆被使用来召开奥运会" + " 运动为:"+ yundong+" 形状为:"+shape+ " 名称为:"+name); } } 建筑工厂类:JianZhuFactory import java.util.*; public class JianZhuFactory { private static final Map<String,TiYuGuan> tygs = new HashMap<String,TiYuGuan>(); public static TiYuGuan getTyg(String yundong){ TiYuGuan tyg = tygs.get(yundong); if(tyg == null){ tyg = new TiYuGuan(yundong); tygs.put(yundong,tyg); } return tyg; } public static int getSize(){ return tygs.size(); } } 测试类:Clienter public class Clienter { public static void main(String[] args) { String yundong ="足球"; for(int i = 1;i <= 5;i++){ TiYuGuan tyg = JianZhuFactory.getTyg(yundong); tyg.setName("中国体育馆"); tyg.setShape("圆形"); tyg.use(); System.out.println("对象池中对象数量为:"+JianZhuFactory.getSize()); } } } 执行结果: 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 三、模式解析 如上示例中,使用工厂模式进行配合,创建对象池,测试类中的循环,你可以想象成为要举行5场比赛,每场比赛的场地就是体育馆 通过执行结果可以看出,在这个对象池(HashMap)中,一直都只有一个对象存在,第一次使用的时候创建对象,之后的每次调用都用的是那个对象,不会再重新创建。 其实在Java中就存在这种类型的实例:String。 Java中将String类定义为final(不可改变的),JVM中字符串一般保存在字符串常量池中,这个字符串常量池在jdk 6.0以前是位于常量池中,位于永久代,而在JDK 7.0中,JVM将其从永久代拿出来放置于堆中。 我们使用如下代码定义的两个字符串指向的其实是同一个字符串常量池中的字符串值。 String s1 = "abc"; String s2 = "abc"; 如果我们以s1==s2进行比较的话所得结果为:true,因为s1和s2保存的是字符串常量池中的同一个字符串地址。这就类似于我们今天所讲述的享元模式,字符串一旦定义之后就可以被共享使用,因为他们是不可改变的,同时被多处调用也不会存在任何隐患。 四、使用场景 当我们项目中创建很多对象,而且这些对象存在许多相同模块,这时,我们可以将这些相同的模块提取出来采用享元模式生成单一对象,再使用这个对象与之前的诸多对象进行配合使用,这样无疑会节省很多空间。

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

Java描述设计模式(10):组合模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 1、文件系统 下图是常见的计算机文件系统的一部分。 文件系统是一个树结构,树上长有节点。树的节点有两种: 树枝节点 即文件夹,有内部树结构,在图中涂有颜色; 树叶节点 另一种是文件,即树叶节点,没有内部树结构。 2、打印文件树结构 public class C01_InScene { public static void main(String[] args) { File file = new File("F:\\tree") ; fileTree(file, 0); } private static void fileTree(File file, int floor) { // 判断是否存在 if (file.exists()) { if (floor > 0) { // 循环打空格 for (int i = 0; i < floor; i++) { System.out.print(" "); } } if (file.isDirectory()) { System.out.println("+" + file.getName()); // 列出所有文件及文件夹 File[] files = file.listFiles(); if (null != files) { // 循环递归 for (File dirFile : files) { fileTree(dirFile, floor + 1); } } } else { System.out.println("-" + file.getName()); } } } } 执行效果:+代表文件夹,-代表文件。 +tree +dir1 +dir2 -dir2Leaf.txt -leaf1.txt -leaf2.txt -OneLeaf.txt -TwoLeaf.txt 3、组合模式描述 组合模式属于对象的结构模式,有时又叫做“部分——整体”模式。组合模式将对象组织到树结构中,可以用来描述整体与部分的关系。组合模式可以使客户端将单纯元素与复合元素同等看待。 二、组合模式-安全式 1、基础概念 安全式的组合模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。涉及到三个角色: 抽象构件(Component)角色 它给组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。组合对象通常把它所包含的子对象当做类型为Component的对象。在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。 树叶构件(Leaf)角色 树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。 树枝构件(Composite)角色 代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如add()、remove()以及getChild()。 2、模式图解 3、源代码实现 public class C02_Security_Model { public static void main(String[] args) { Composite root = new Composite("服装"); Composite composite1 = new Composite("男装"); Leaf manCoat = new Leaf("上衣"); Leaf manBottom = new Leaf("下衣"); composite1.addChild(manCoat); composite1.addChild(manBottom); Composite composite2 = new Composite("女装"); Leaf leaf1 = new Leaf("鞋子"); Leaf leaf2 = new Leaf("帽子"); root.addChild(leaf1); root.addChild(leaf2); root.addChild(composite1); root.addChild(composite2); root.printStruct(""); } } // 抽象构件角色类 interface Component { /* * 输出组件自身的名称 */ void printStruct(String preStr); } // 树枝构件角色类 class Composite implements Component{ // 用来存储组合对象中包含的子组件对象 private List<Component> childComponents = new ArrayList<Component>(); // 输出对象的名称 private String name; // 构造方法,传入组合对象的名字 public Composite (String name){ this.name = name; } /** * 聚集管理方法,增加一个子构件对象 * @param child 子构件对象 */ public void addChild(Component child){ childComponents.add(child); } /** * 聚集管理方法,删除一个子构件对象 * @param index 子构件对象的下标 */ public void removeChild(int index){ childComponents.remove(index); } /** * 聚集管理方法,返回所有子构件对象 */ public List getChild(){ return childComponents ; } /** * 输出对象的自身结构 * @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进 */ @Override public void printStruct(String preStr) { //先输出自己 System.out.println(preStr+"+"+this.name); //如果还包含有子组件,那么就输出这些子组件对象 if (this.childComponents != null){ //添加两个空格,表示向后缩进两个空格 preStr = preStr+" "; //输出当前的子对象:使用函数递归的原理 for (Component c : childComponents) { c.printStruct(preStr); } } } } class Leaf implements Component{ // 输出叶子对象的名称 private String name; // 构造方法,传入叶子对象的名称 public Leaf (String name){ this.name = name ; } /** * 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字 * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进 */ @Override public void printStruct(String preStr) { System.out.println(preStr+"-"+name); } } 输出结果 +服装 -鞋子 -帽子 +男装 -上衣 -下衣 +女装 三、组合模式-透明式 1、概念图解 与安全式的组合模式不同的是,透明式的组合模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定接口。 2、源代码实现 public class C03_Transparent_Model { public static void main(String[] args) { Component1 root = new Composite1("服装"); Component1 c1 = new Composite1("男装"); Component1 c2 = new Composite1("女装"); Component1 leaf1 = new Leaf1("衬衫"); Component1 leaf2 = new Leaf1("夹克"); Component1 leaf3 = new Leaf1("裙子"); Component1 leaf4 = new Leaf1("套装"); root.addChild(c1); root.addChild(c2); c1.addChild(leaf1); c1.addChild(leaf2); c2.addChild(leaf3); c2.addChild(leaf4); root.printStruct(""); } } abstract class Component1 { /** * 输出组件自身的名称 */ public abstract void printStruct(String preStr); // 聚集管理方法,增加一个子构件对象 public void addChild(Component1 child){ /** * 缺省实现,抛出异常,因为叶子对象没有此功能 * 或者子组件没有实现这个功能 */ throw new UnsupportedOperationException("对象不支持此功能"); } // 聚集管理方法,删除一个子构件对象 public void removeChild(int index){ /** * 缺省实现,抛出异常,因为叶子对象没有此功能 * 或者子组件没有实现这个功能 */ throw new UnsupportedOperationException("对象不支持此功能"); } // 聚集管理方法,返回所有子构件对象 public List<Component1> getChild(){ /** * 缺省实现,抛出异常,因为叶子对象没有此功能 * 或者子组件没有实现这个功能 */ throw new UnsupportedOperationException("对象不支持此功能"); } } class Composite1 extends Component1 { // 用来存储组合对象中包含的子组件对象 private List<Component1> childComponents = new ArrayList<Component1>(); // 输出对象名称 private String name ; public Composite1 (String name){ this.name = name; } /** * 聚集管理方法,增加一个子构件对象 * @param child 子构件对象 */ public void addChild(Component1 child){ childComponents.add(child); } /** * 聚集管理方法,删除一个子构件对象 * @param index 子构件对象的下标 */ public void removeChild(int index){ childComponents.remove(index); } // 聚集管理方法,返回所有子构件对象 public List<Component1> getChild(){ return childComponents ; } /** * 输出对象的自身结构 * @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进 */ @Override public void printStruct(String preStr) { // 首先输出自己名称 System.out.println(preStr+"+"+this.name); // 如果还包含有子组件,那么就输出这些子组件对象 preStr = preStr + " "; if (this.childComponents != null) { // 添加两个空格,表示向后缩进 for (Component1 c : childComponents) { ////递归输出每个子对象 c.printStruct(preStr); } } } } class Leaf1 extends Component1 { private String name; public Leaf1 (String name){ this.name = name; } /** * 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字 * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进 */ @Override public void printStruct(String preStr) { System.out.println(preStr+"-"+name); } } 四、JDK中应用 1、HashMap结构图 2、分层结构 interface Map class AbstractMap implements Map HashMap extends AbstractMap implements Map interface Map.Entry Node implements Map.Entry 3、源代码 存储叶子节点 public V put(K var1, V var2) { return this.putVal(hash(var1), var1, var2, false, true); } final V putVal(int var1, K var2, V var3, boolean var4, boolean var5) { HashMap.Node[] var6 = this.table; ....... } 存储树枝节点 public void putAll(Map<? extends K, ? extends V> var1) { this.putMapEntries(var1, true); } 五、源代码地址 GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

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

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等操作系统。

用户登录
用户注册