Design pattern
设计原则SOLID
Single Responsibility Principle
表明一个类只具备一个职责
Open Close Principle
一个类应该对扩展开发,修改关闭
//设计一个关于api请求数相关告警类 public class Alert { private AlertRule rule; private Notification notification; public Alert(AlertRule rule, Notification notification) { this.rule = rule; this.notification = notification; } public void check(String api, long requestCount, long errorCount, long durationSeconds) { long tps = requestCount / durationSeconds; if (tps > rule.getMatchedRule(api).getMaxTps()) { notification.notify("...") } if (errorCount > rule.getMatchedRule(api).getMaxErrorCount())) { notification.notify("...") } } }
如果我们需要添加一个功能,当每秒钟接口超时请求个数,超过某个阈值时,也发送告警通知。那么如何改动代码
public class Alert { private AlertRule rule; private Notification notification; public Alert(AlertRule rule, Notification notification) { this.rule = rule; this.notification = notification; } public void check(String api, long requestCount, long errorCount, long timeoutCount, long durationSeconds) { long tps = requestCount / durationSeconds; if (tps > rule.getMatchedRule(api).getMaxTps()) { notification.notify("...") } if (errorCount > rule.getMatchedRule(api).getMaxErrorCount())) { notification.notify("...") } long timeoutTps = timeoutCount / durationOfSeconds; if (timeoutTps > rule.getMatchedRule(api).getMaxTimeoutTps()) { notification.notify("...") } } }
这样修改意味着调用这个接口的代码都做相应的修改,另一方面,修改了check函数相应的单元测试也需要修改
//新的修改方式 public class Alert { private List<AlertHandler> alertHandlers = new ArrayList<>(); public void addAlertHandler(AlertHandler alertHandler) { this.alertHandlers.add(alertHanlder); } public void check(ApiStatInfo apiStatInfo) { handler.check(apiStatInfo) } } public abstract class AlertHandler { AlertRule rule; Notification notification; public abstract void check(ApiStatInfo apiStatInfo); }
在讲具体的方法论之前,我们先来看一些更加偏向顶层的指导思想。为了尽量写出扩展性好的代码,我们要时刻具备扩展意识、抽象意识、封装意识。这些"潜意识"可能比任何开发技巧都重要。在试别出代码可变部分和不可变部分之后,我们要将可变部分封装起来,隔离变化,提供抽象化的不可变接口,给上层系统使用。当具体的实现发生变化时,我们只需要基于相同的抽象接口,扩展一个新的实现,替换掉老的实现即可
开闭原则不是免费的。有些情况下,代码的扩展性和可读性是存在冲突的。
L Substitution Principle
将一个基类对象替换成它的子类对象,程序将不会产生错误和异常,反过来则不成立。这要求子类不要重写基类函数
Interface Segregation Principle
类不应该被迫依赖他们不使用的方法
Dependency Inversion Principle
高层模块不应该依赖底层模块。在类之间存在依赖关系的情况下,应使用抽象来定义他们,而不是直接引用类,这减少了由较低级别模块的变化导致高层的错误
设计模式
创建型
解决对象的创建问题
单例模式
//静态创建 InitObject()
//动态创建 GetObject()
工厂模式
工厂模式是一种实例化对象模式。在当前面向对象编程中,类是对现实世界中某种事物的描述,工厂是对类进行一个组装,产生另外一种产品的设计方法
结构型
解决对象组装的我呢提
代理模式
代理模式为其他对象提供一种代理以控制这个对象的访问,在客户端和目标对象之间起到中介的作用
在不改变代码的情况下,通过引入代理类来给原始类附加功能。一般应用于框架代码和业务代码解耦
装饰者模式
适配器模式
适配器、代理和装饰都是通过组合/集成一个现存对象、通过调用该对象的方法来实现自己的功能,它们之间很相像。但从意图上来分析,代理模式着重将复杂部分抽到中间层来控制目标对象的访问,它要求代理层和目标对象接口相同;而适配器解决的是接口之间不能正常工作的问题;装饰模式强调动态扩展对象功能
行为型
解决对象之间交互的问题
观察者模式
观察者模式包含两个角色: 观察者和被观察对象.观察者行为根据被观察对象而改变
策略模式
职责链模式
状态模式