浅谈几个设计模式

75 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

设计模式

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。

即:设计模式就是面向对象设计里面 对反复出现问题的一种解决方案。

分类

总共有 23 种设计模式。这些模式可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)

创建型模式

提供在创建对象的同时,隐藏创建逻辑的方式,而不是直接new

包括

  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 单例模式(Singleton Pattern)
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype Pattern)

结构型模式

关注类和对象组合,用来组合接口和定义组合对象获得新功能

包括:

  • 适配器模式(Adapter Pattern)
  • 桥接模式(Bridge Pattern)
  • 过滤器模式(Filter、Criteria Pattern)
  • 组合模式(Composite Pattern)
  • 装饰器模式(Decorator Pattern)
  • 外观模式(Facade Pattern)
  • 享元模式(Flyweight Pattern)
  • 代理模式(Proxy Pattern)

行为型模式

关注对象之间通信

包括

  • 责任链模式(Chain of Responsibility Pattern)
  • 命令模式(Command Pattern)
  • 解释器模式(Interpreter Pattern)
  • 迭代器模式(Iterator Pattern)
  • 中介者模式(Mediator Pattern)
  • 备忘录模式(Memento Pattern)
  • 观察者模式(Observer Pattern)
  • 状态模式(State Pattern)
  • 空对象模式(Null Object Pattern)
  • 策略模式(Strategy Pattern)
  • 模板模式(Template Pattern)
  • 访问者模式(Visitor Pattern)

J2EE

关注表示层

包括

  • MVC 模式(MVC Pattern)
  • 业务代表模式(Business Delegate Pattern)
  • 组合实体模式(Composite Entity Pattern)
  • 数据访问对象模式(Data Access Object Pattern)
  • 前端控制器模式(Front Controller Pattern)
  • 拦截过滤器模式(Intercepting Filter Pattern)
  • 服务定位器模式(Service Locator Pattern)
  • 传输对象模式(Transfer Object Pattern)

设计模式六大原则

  1. 开闭原则:对拓展开发,对修改关闭
  2. 里氏代换原则:任何基类可以出现的地方,子类一定可以出现
  3. 依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体。
  4. 接口隔离原则:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度
  5. 最少知道原则:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
  6. 合成复用原则:尽量使用合成/聚合的方式,而不是使用继承。

工厂模式

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

比如你想要一个电脑,你不需要知道电脑内部怎么连接,只需要知道,你要一个电脑。

优点:扩展性好

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖

在进行数据库访问时候,当不知道系统最后采用哪一种,以及数据库会变化时候,使用

实现:定义一个类实现一个接口,并重写方法,创建一个工程,生成实体类对象,通过工厂传递对象

interface Computer {
    public  void run();
}

class ComputerA implements Computer {

    public void run(){

        System.out.println("电脑1");
    }
}

class ComputerB implements Computer {
    public void run(){
        System.out.println("电脑2");
    }

}

工厂
class Factory {
    public Computer createComputer(String name)
    {
        if (name.equalsIgnoreCase("ComputerA")) {
            return new ComputerA();
        }
        else if (name.equalsIgnoreCase("ComputerB")) {
            return new ComputerB();
        }
        return null;
    }
}

class SimpleFactoryClient{
    public static void main(String[] args) {
        Factory factory = new Factory();
       Computer Computer1= factory.createComputer("ComputerA"); //给个名,工厂就生产
        Computer1.run();
       Computer Computer2= factory.createComputer("ComputerB");
        Computer2.run();
    
    }
}

单例模式

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。 参考文章:单例设计模式 - 掘金 (juejin.cn)

桥接模式-Java数据库连接库JDBC用的设计模式

我们大家都熟悉,顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来,而这两个被联系起来的结构可以独立的变化,所有其他的理解只要建立在这个层面上就会比较容易。

UML图如下

image.png

在不使用Spring、Hibernate等第三方库的情况下,直接通过原生JDBC API连接MySQL数据库,则有如下示例代码:

Class.forName("com.mysql.cj.jdbc.Driver");  
Connection conn = DriverManager.getConnection("jdbc:mysql://<host>:<port>/<database>");
  • Class.forName()方法

该方法将返回与给定字符串名的类或接口相关联的java.lang.Class类对象,用于在程序运行时的某个时刻,由客户端调用,动态加载该类或该接口到当前线程中

  • com.mysql.cj.jdbc.Driver类

MySQL将具体的java.sql.Driver接口的实现放到了NonRegisteringDriver中,com.mysql.cj.jdbc.Driver类仅包含一段静态代码,具体类图如下:

  • DriverManager类

由上面的分析可得,Class.forName()方法调用后,com.mysql.cj.jdbc.Driver类被加载,并执行static 静态代码段,将com.mysql.cj.jdbc.Driver类实例注册到DriverManager中。然后,客户端会调用DriverManager.getConnection()方法获取一个Connection数据库连接实例

  • Connection接口

Connection代表和特定数据库的连接会话,能够执行SQL语句并在连接的上下文中返回执行结果 以上述JDBC在MySQL中的简略类图为例,抽象化部分有Driver接口和Connection接口,实现化部分有DriverManager。对于不同的数据库,Driver接口和Connection接口都有自己独特的实现类

关于jdbc是策略模式还是桥接模式

我看网上有很多答案,但是这个题是我在牛客刷到的,我不太了解策略模式,但是我觉得从设计的目的来看,JDBC采用的并不是策略模式,在一段程序中数据库驱动并不存在频繁地相互替换(策略模式中,一个类的行为或其算法可以在运行时更改。)