JAVA设计模式面试复习

设计模式

为什么要用设计模式?

设计模式是编程随时间发展下来总结的经验和套路,它可以让写出来的代码复用性更好、拓展性更强、易于维护等等优点

设计模式的类型

创建型模式

提供一种在创建对象的同时隐藏创建逻辑的方式,让程序在不同情境下可以灵活的选择创建对象的类型

工厂模式、抽象工厂模式、单例模式、建造者模式等

结构型模式

 

常见的设计模式

工厂模式

意图:定义一个工厂接口,实现不同的创建对象方式,使用者直接使用实现类创建对象。

优点:

  1. 可以屏蔽复杂的创建过程,调用者只关心通过哪个工厂创建。

  2. 扩展性强,如果需要添加一种创建方式,只需要实现一个新的工厂类

缺点:

  1. 每次定义一种类的时候就需要一个配套的对象工厂,一定程度上增加了复杂度,所以如果简单的类型直接new就好了。

使用场景:

  1. Spring的BeanFactory接口就是工厂模式,它的实现类可以通过配置文件的信息生产Bean,也可以通过getBean获取实例时就是向工厂获取指定的Bean

抽象工厂模式

与简单工厂模式的区别

简单工厂模式只针对单个”产品的生产“,而抽象工厂模式中有多个产品需要生产,并且各个产品之间又有依赖关系。

例子:

我们需要生产矿泉水,如果用简单工厂模式就是需要三个工厂,一个产水一个产瓶子,然后还要有一个工厂把水填进瓶子里。显然水和瓶子是有逻辑上的关系的,使用抽象工厂模式后,在抽象工厂中定义生产水、生产瓶子和灌装水的方法,具体的实现类都实现后就可以在一个工厂中生产出矿泉水了。

单例模式

意图: 保证一个类只有一个实例,全局只访问这一个,避免一个相同的类被频繁的创建和销毁

例子:

  1. Spring当中的Bean默认都是单例模式

  2. 计数器使用的也是单例,然后保证同步访问。

  3. 数据库的连接池也算吧,固定几个连接,它们都是不同的对象,可以理解成单个?然后实现复用

懒汉式实现

//懒汉式实现是在实际使用时才创建
public class Singleton {
  private static Singleton singleton = null;
  // 构造得声明成私有的,不会被外部随意实例化
  private SingleTon(){}
  // 方法体加锁
  public static synchronized SingleTon() {
    if (singleton == null) {
      singleton = new Singleton();
    }
    return singleton;
  }
  // 双重锁定
  public static SingleTon() {
    // 两次判空是因为,等待锁时可能已经被人初始化过了,如果不再判断可能会重复初始化。
    if (singleton == null) {
      synchronized(this) {
        if (singleton == null) {
          singleton = new Singleton(); 
        } 
      }
    }
    return singleton;
  }
}

饿汉式实现

// 饿汉式在类初始化时就已经初始化了静态实例
public class Singleton {
  private static Singleton singleton = new Singleton();
  private SingleTon(){}
  
  public static SingleTon() {
    return singleton;
  }
}

建造者模式

意图: 将一个复杂对象的创建分离成各个步骤,使得一个复杂对象可以在多次组合当中创建出来。

实例:

  1. StringBuilder就是其中一种,例如输出一段日志的前缀都是相同的,但是程序执行中可能成功或者失败,那么可以根据不同的结果append拼接,最后组合出整个字符串对象。

适配器模式

意图: 适配器模式使得原本不相兼容的接口可以一起工作,日常生活中常见的图片查看器就是一种“适配器”,可以查看不同格式的图片。

实例:

  1. SpringMVC中就有HandleAdepter,用于适配Controller的不同实现方式(注解、配置、实现Controller接口、实现HTTPRequestHandle接口)的调用。

实现

public interface JPG extend PictureFormat{
  void display();
} 
public class JPGPlayer{
  void display(){
    ....
  }
}
public interface PicturePlayer {
  void displayPicture();
}
​
public class PlayerAdepter implement PicturePlayer{
  PictureFormat format = null;
  public PlayerAdepter(PictureFormat format){
    this.format = format;
  }
  
  void displayPicture() {
    // 额外处理
    format.display();
    // 额外处理
  }
}

装饰器模式

意图: 动态地给一个对象添加一些额外的功能,同时不改变其原有的结构。相比起继承装饰者模式更加灵活。

实例:

  1. JDK 中Collections.SynchronizedMap,生成线程安全的集合类,将其所有修改方法都加上了同步锁

实现:

public interface Human {
  void talk();
}
public class Man implement Human{
  void talk(){
    //打印hello
  }
}
​
public abstract class HumanDecorator implement Human {
  private Human human = null;
  public HumanDecorator(Human human) {
        this.human = human;
  }
  void talk() {
    human.talk();
  }
}
​
public class StudentDecorator extends HumanDecorator {
  public StudentDecorator(Human human) {
        super(human);
  }
  
  @Override
  void talk() {
    human.talk();
    readBook();
  }
  
  private void readBook(){
    //读书
  }
}

代理模式

意图: 为其他对象提供一种代理的方式控制这个对象的访问。

实例:

  1. JDK中的动态代理

  2. Spring AOP

与适配器模式的区别

适配器模式需要考虑其中对不同对象的适配,代理模式代理的对象一旦确定是不能改变的

与装饰者模式的区别

其实差别不大,只是使用的本意不同,装饰器模式是为了增加额外的功能,代理模式是为了加以控制

实现:

静态代理、动态代理、

观察者模式

意图: 定义对象之间一种一对多的依赖关系,当一个对象的状态发生改变时,通知依赖于它的观察者对象执行对应的处理方法。它类似于广播通讯。用途可以用于广播通知更改、也可以做一个回调机制

实例:

  1. Spring的事件驱动模型就是观察者模式的应用,它有各种Listener对应到各个事件中,例如ApplicationContext初始化完成后打印日志、Environment环境对象初始化完成后读取用户的Application.properties等等

实现:

  1. 首先得定义事件类型Event,和一个或者多个Listener,Listener统一实现一个接口的事件触发执行方法。

  2. 事件中心类EventObject中维护Event和Listener的一对多关系。

  3. 从事件中心类中发布事件后,调用对应事件中的所有观察者。

策略模式

意图: 定义一系列函数,把他们封装起来,并且使他们之间能互相替换,它可以解决在有多种解决方式的情况下使用if..else所带来的复杂度。

实现:

public interface Strategy{
void algorithmInterface();
}
public class ConcreteStrategyA extends Strategy {
 @Override
 public void algorithmInterface() {
     System.out.println("算法A实现");
 }
}
public class ConcreteStrategyB extends Strategy {
 @Override
 public void algorithmInterface() {
     System.out.println("算法B实现");
 }
}
public class Client {
​
 public static void main(String[] args) {
     Context context;
     
     context = new Context(new ConcreteStrategyA());
     context.contextInterface();
     
     context = new Context(new ConcreteStrategyB());
     context.contextInterface();
     
     context = new Context(new ConcreteStrategyC());
     context.contextInterface();
 }
​
}

模板模式

意图:定义一个程序执行流程的骨架,封装好公共的步骤,将一些步骤延迟到子类当中实现。

实例:

Spring中的各种Template类,RedisTemplate、JDBCTemplate等

实现:

public abstract class Template {
    abstract void run();
    abstract void destroy();
    void init() {
        System.out.println("初始化");
    }
    public final void play(){
        init();
        run();
        destroy();
    }
}
​
class GameTemplate extends Template {
    @Override
    void run() {
        System.out.println("执行");
    }
    @Override
    void destroy() {
        System.out.println("销毁");
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值