java - 将状态模式与虚拟代理一起使用是否有意义?
问题描述
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();
}
}
这个解决方案有意义吗?
代码有什么可能的改进吗?
有没有以前做过的类似事情的例子?
这是不必要的并发症还是值得还是取决于情况?
它会使代码更快吗?我的意思是,额外的函数调用可能比简单的条件调用要慢。
解决方案
这是不必要的并发症还是值得还是取决于情况?
虽然在使用状态模式时只有 2 个状态是完全可以的,但在这种特殊情况下,这绝对是一种过度杀伤,原因如下:
UninitializedState
从->只会有一个状态转换InitailizedState
。一旦HeavyWeightObjcet
被初始化,你绝对不会在从InitializedState
->转换之间交替,UninitializedState
反之亦然- 我们有YAGNI(你不需要它)和KISS(保持简单,愚蠢)之类的设计原则是有原因的。不要在代码的第一次迭代中引入复杂性。让设计演变为持续重构的一部分。
- 虽然上面的例子在纸面上看起来不错,但现实世界是完全不同的球赛。在现实世界的代码中还有更重要的问题需要解决。(例如,
operate
方法是线程安全的吗?)
它会使代码更快吗?我的意思是,额外的函数调用可能比简单的条件调用要慢。
在性能方面,这个区域太小了,无需担心阅读:微优化
最后但并非最不重要的一点是,状态模式允许我们坚持开闭原则。. operate
就示例而言,就初始化而言,没有令人信服的理由来改变方法HeavyWeightObject
。此外,初始化代码首先应该在构造函数中而不是operate
方法中。
推荐阅读
- node.js - 基于 Node.js 和 AWS 开发全栈应用程序时的推荐实践
- excel - 根据 Excel 中的日期范围返回单元格的值
- swiper - Swiperjs 淡入淡出过渡没有正确交叉淡入淡出,而是添加了白色交叉过渡效果
- windows - 在 Mattermost 上运行服务器时出现 Unicode 错误?
- android - 运行 Gradle 任务“assembleDebug”。(这需要很长时间。)
- amazon-web-services - 使用 AWS Toolkit for Cloud9 在本地导入、编辑和调试 Lambda 函数
- java - Spring Boot 5 中的持久化 API 令牌
- typescript - Nest.js Graphql Nested InputType 抛出引用错误
- azure - 如何使用其他 Azure 服务对 IoT Central 设备进行身份验证?(例如:下载OTA bin)
- c# - 文档 | 为什么 API 返回“资源不支持 http 方法 'POST'” | C#