首页 > 解决方案 > 将状态模式与虚拟代理一起使用是否有意义?

问题描述

class HeavyweightObjcet
{
    public void operate() {
        System.out.println("Operating...");
    }
}

class LazyInitializer
{
    HeavyweightObjcet objcet;

    public void operate()
    {
        if (objcet == null)
            objcet = new HeavyweightObjcet();
        objcet.operate();
    }
}

在这里,我正在为重量级对象制作虚拟代理。每次调用之前HeavyweightObject::operate,程序首先检查对象是否null存在。这部分在对象的整个生命周期中被检查一次且仅一次。

一个可能的改进可能是使用这样的状态模式:

class HeavyweightObjcet
{
    public void operate() {
        System.out.println("Operating...");
    }
}

class LazyInitializer
{
    HeavyweightObjcet objcet;
    State state = new UninitializedState(this);

    public void operate()
    {
        state.operate();
    }
}

abstract class State
{
    LazyInitializer initializer;

    public State(LazyInitializer initializer)
    {
        this.initializer = initializer;
    }

    abstract void operate();
}

class UninitializedState extends State
{
    public UninitializedState(LazyInitializer initializer) {
        super(initializer);
    }

    @Override
    public void operate() {
        initializer.objcet = new HeavyweightObjcet();
        initializer.state = new InitializedState(initializer);
        initializer.operate();
    }
}

class InitializedState extends State
{
    public InitializedState(LazyInitializer initializer) {
        super(initializer);
    }

    @Override
    public void operate() {
        initializer.objcet.operate();
    }
}

这个解决方案有意义吗?

代码有什么可能的改进吗?

有没有以前做过的类似事情的例子?

这是不必要的并发症还是值得还是取决于情况?

它会使代码更快吗?我的意思是,额外的函数调用可能比简单的条件调用要慢。

标签: javaoopdesign-patternslazy-initializationstate-pattern

解决方案


这是不必要的并发症还是值得还是取决于情况?

虽然在使用状态模式时只有 2 个状态是完全可以的,但在这种特殊情况下,这绝对是一种过度杀伤,原因如下:

  1. UninitializedState从->只会有一个状态转换 InitailizedState。一旦HeavyWeightObjcet 被初始化,你绝对不会在从InitializedState->转换之间交替,UninitializedState反之亦然
  2. 我们有YAGNI(你不需要它)和KISS(保持简单,愚蠢)之类的设计原则是有原因的。不要在代码的第一次迭代中引入复杂性。让设计演变为持续重构的一部分。
  3. 虽然上面的例子在纸面上看起来不错,但现实世界是完全不同的球赛。在现实世界的代码中还有更重要的问题需要解决。(例如,operate方法是线程安全的吗?)

它会使代码更快吗?我的意思是,额外的函数调用可能比简单的条件调用要慢。

在性能方面,这个区域太小了,无需担心阅读:微优化

最后但并非最不重要的一点是,状态模式允许我们坚持开闭原则。. operate就示例而言,就初始化而言,没有令人信服的理由来改变方法HeavyWeightObject。此外,初始化代码首先应该在构造函数中而不是operate方法中。


推荐阅读