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()
    
  • 工厂模式

    工厂模式是一种实例化对象模式。在当前面向对象编程中,类是对现实世界中某种事物的描述,工厂是对类进行一个组装,产生另外一种产品的设计方法

结构型

解决对象组装的我呢提

  • 代理模式

    代理模式为其他对象提供一种代理以控制这个对象的访问,在客户端和目标对象之间起到中介的作用

    在不改变代码的情况下,通过引入代理类来给原始类附加功能。一般应用于框架代码和业务代码解耦

  • 装饰者模式

  • 适配器模式

适配器、代理和装饰都是通过组合/集成一个现存对象、通过调用该对象的方法来实现自己的功能,它们之间很相像。但从意图上来分析,代理模式着重将复杂部分抽到中间层来控制目标对象的访问,它要求代理层和目标对象接口相同;而适配器解决的是接口之间不能正常工作的问题;装饰模式强调动态扩展对象功能

行为型

解决对象之间交互的问题

  • 观察者模式

    观察者模式包含两个角色: 观察者和被观察对象.观察者行为根据被观察对象而改变

  • 策略模式

  • 职责链模式

  • 状态模式

无用的设计模式

关于面向对象和面向过程的区别阐述