将状态模式与虚拟代理一起使用是否有意义?

问题描述 投票:3回答:2
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();
    }
}

此解决方案有意义吗?

代码是否有可能改进?

以前有没有类似的例子?

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

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

java oop design-patterns lazy-initialization state-pattern
2个回答
0
投票

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

虽然使用State Pattern时仅具有两个状态是完全可以的,但由于以下原因,在这种特殊情况下绝对是一个过大的杀伤力:

  1. [UninitializedState-> InitailizedState。一次HeavyWeightObjcet已经初始化,您绝对不会从InitializedState-> UninitializedState过渡或反之亦然
  2. [我们之所以有设计原则,例如YAGNI (不需要)和KISS(保持简单,愚蠢)是有原因的。不要在代码的第一次迭代中引入复杂性。让设计作为连续重构的一部分而发展。
  3. 虽然上面的示例在纸面上看起来不错,但现实世界完全是另一回事。在现实世界中的代码中还有更多重要的问题要解决。 (例如,operate方法是线程安全的吗?)

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

这是一个很小的区域,不必担心性能Read : micro-optimization

最后但并非最不重要的是,状态模式允许我们遵守Open-Closed principle.。如示例所示,就operate的初始化而言,没有令人信服的理由更改HeavyWeightObject方法。此外,初始化代码应位于构造函数中,而不要首先位于operate方法中。


0
投票

虽然使用状态模式时仅具有两个状态是完全可以的,但由于以下原因,在这种特定情况下,绝对是过大的杀伤力:

从UninitializedState-> InitailizedState将只有一个状态转换。一旦HeavyWeightObjcet初始化完成,您绝对不会在从InitializedState-> UninitializedState转换之间进行切换,反之亦然我们之所以拥有诸如YAGNI(您不需要它)和KISS(保持简单,愚蠢)之类的设计原理是有原因的。不要在代码的第一次迭代中引入复杂性。让设计作为连续重构的一部分而发展。尽管上面的示例在纸面上看起来不错,但现实世界完全是另一回事。在现实世界中的代码中还有更多重要的问题要解决。 (例如,操作方法是否是线程安全的?)

© www.soinside.com 2019 - 2024. All rights reserved.