设计模式

113 阅读3分钟

1、单例模式

  • 单例对象的类必须保证只有一个实例存在,整个系统只能使用一个对象实例。
  • 优点:不会频繁地创建和销毁对象,浪费系统资源。
  • 使用场景:IO 、数据库连接、Redis 连接等。

懒汉式

  • 什么时候用什么时候创建
  • 懒汉式可能导致线程安全问题,使用synchronized或者加锁方式可以防止。
public class SingletonLazy {

    private static SingletonLazy instance;

    private SingletonLazy(){};

    public static synchronized SingletonLazy getInstance(){
        if (null == instance){
            instance =  new SingletonLazy();
        }
        return instance;
    }
}

饿汉式

  • 先创建好,用的时候直接拿,有点浪费内存。
  • 不会导致线程安全问题。
public class SingletonHungry {

    private static SingletonHungry instance = new SingletonHungry();

    private SingletonHungry(){};

    public static SingletonHungry getInstance(){
        return instance;
    }
}

2、简单工程模式

简单工厂模式又叫静态工厂方法模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。比如,一台咖啡机就可以理解为一个工厂模式,你只需要按下想喝的咖啡品类的按钮(摩卡或拿铁),它就会给你生产一杯相应的咖啡,你不需要管它内部的具体实现,只要告诉它你的需求即可。

优点

  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量;
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性

缺点

  • 不易拓展,一旦添加新的产品类型,就不得不修改工厂的创建逻辑;
  • 产品类型较多时,工厂的创建逻辑可能过于复杂,一旦出错可能造成所有产品的创建失败,不利于系统的维护。
public class EasyFactory {

    public static void main(String[] args) {
        System.out.println(EasyFactory.createProduct("香蕉"));
    }

    public static String createProduct(String name){
        String product = null;
        switch (name) {
            case "苹果":
                product = "苹果";
                break;
            case "香蕉":
                product = "香蕉";
                break;
            default:
                product = "没有对应商品";
        }
        return product;
    }
}

3、抽象工厂模式

抽象工厂模式是在简单工厂的基础上将未来可能需要修改的代码抽象出来,通过继承的方式让子类去做决定。

//抽象工厂
abstract class AbstractFactory {
    public abstract String createProduct(String name);
}
//咖啡工厂
public class CoffeeFactory extends AbstractFactory {
    @Override
    public String createProduct(String name) {
        String product = null;
        switch (name) {
            case "摩卡":
                product = "摩卡";
                break;
            case "雀巢":
                product = "雀巢";
                break;
            default:
                product = "没有对应商品";
        }
        return product;
    }
}

4、代理模式

代理模式是给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

优点

  • 在一定程度上降低了系统的耦合度。
  • 可以灵活地隐藏被代理对象的部分功能和服务,也额外增加功能和服务。

缺点

  • 由于使用了代理模式,因此程序的性能没有直接调用性能高。
  • 使用代理模式提高了代码的复杂度。

生活例子

举一个生活中的例子:比如买飞机票,由于离飞机场太远,直接去飞机场买票不太现实,这个时候我们就可以上携程 App 上购买飞机票,这个时候携程 App 就相当于是飞机票的代理商。

//售票接口
public interface IAirTicket {
    void buy();
}
//飞机场售票站
public class AirTicket implements IAirTicket {
    @Override
    public void buy() {
        System.out.println("买票");
    }
}
//代理购票平台(携程)
public class ProxyAirTicket implements IAirTicket{
    private AirTicket airTicket;

    public ProxyAirTicket() {
        airTicket = new AirTicket();
    }

    @Override
    public void buy() {
        airTicket.buy();
    }
}
//测试
public class ProxyTest {
    public static void main(String[] args) {
        IAirTicket airTicket = new ProxyAirTicket();
        airTicket.buy();
    }
}