今天是:
带着程序的旅程,每一行代码都是你前进的一步,每个错误都是你成长的机会,最终,你将抵达你的目的地。
title

空对象模式(Null Object Pattern)

定义

空对象用于创建一个代表空或无效对象的实例,而无需使用 null。这个模式允许在对象不存在或不可用时提供默认行为,同时避免了对空引用的检查。

意图

大多数面向对象的编程语言(如Java或C#)中,引用可能为null。在调用任何方法之前,需要检查这些引用确保它们不是null,因为通常无法在null引用上调用方法。而不是使用null引用来表示对象的缺失(例如,一个不存在的客户),可以使用实现了期望接口但其方法体为空的对象。这种方法的优势在于相比于一个工作中的默认实现,空对象是非常可预测的,没有任何副作用:它什么都不做。

参与者(角色)​​​​​​

  • 抽象类或接口(Abstract Class or Interface): 定义了具体实现对象的接口或抽象类。

  • 具体对象(Concrete Objects): 实现了抽象类或接口的具体类。

  • 空对象(Null Object): 实现了抽象类或接口,但其方法体为空。通常在需要引用对象但不想或不能使用实际对象时使用空对象,以确保不会出现Null引用异常。

举例

已创建订单为例

类图:

 

这个例子中对应类的角色如下:

  • 抽象类或接口(Abstract Class or Interface): Order

  • 具体对象(Concrete Objects): RealOrder

  • 空对象(Null Object): NullOrder

 

Order类 ,抽象类

public abstract class Order {

    String orderId;

    void process(String orderId) {

    }

}

 

RealOrder类

@Slf4j
public class RealOrder extends Order{
    public RealOrder(String orderId) {
        this.orderId=orderId;
    }

    @Override
    public void process(String orderId) {
            log.info("订单处理成功,订单id:{}",orderId);
    }
}

 

NullOrder空对象类

@Slf4j
public class NullOrder extends Order{

    public NullOrder(String orderId) {
        this.orderId=orderId;
    }

    @Override
    public void process(String orderId) {
        log.info("订单不存在,订单id:{}",orderId);

    }
}

 

OrderFactory订单工厂

public  class OrderFactory {
    static List datas = List.of("1","3","5","6");


    static Order  getOrder(String orderId){
        boolean match = datas.stream().anyMatch(o -> o.equals(orderId));
        if(match)
            return  new RealOrder(orderId);
        else
            return new NullOrder(orderId);
    }
}

 

测试

对与不存在订单也可以和存在的定义一样处理,而不用单独做判断

public class App {
    public static void main(String[] args) {

        List<Order> orders = new ArrayList();

        orders.add(OrderFactory.getOrder("1"));
        orders.add(OrderFactory.getOrder("3"));
        orders.add(OrderFactory.getOrder("7"));

        orders.forEach(o -> o.process(o.orderId));
    }
}

 

优点

  1. 避免空引用异常: 空对象确保在需要对象引用但没有实际对象时不会出现空引用异常。

  2. 简化代码: 可以减少在代码中进行空值检查的需求,简化了对空对象的处理。

  3. 预测性: 空对象的行为是明确的且无副作用,因此在使用空对象时更可预测。

  4. 隐藏实现细节: 可以隐藏在特定情况下的空对象实现细节,使使用者无需关注特定对象是否为空。

  5. 默认行为: 可以提供默认行为,使系统在没有实际对象时有一个可行的默认实现。

缺点

  1. 引入了更多的类,可能导致系统变得复杂

空对象模式的应用

java Optional

public static void main(String[] args) {
        Person person =null;
        Optional<Person> optional = Optional.ofNullable(person);
        log.info("option is null:{}",optional.isEmpty());
        log.info("option is persent:{}",optional.isPresent());
        Person person1 = optional.orElse(new Person());
        person1.setName("zlennon");
        log.info("defalut value:{}",person1.toString());
}

 

 

 

分享到:

专栏

类型标签

网站访问总量