状态模式和享元模式

3

有人能分享一下如何使用状态模式享元模式的例子吗?(享元模式用于创建状态对象以节省内存)

更新: 如何同时使用状态模式和享元模式?


你有两个问题,每个问题都涉及一个模式。请将其中一个问题移动到另一个问题中。 - jgauffin
每个维基页面都有一个Java示例。 - Brian Roach
1
据我所见,他只问了一个问题,即如何使用状态和 fw 模式的组合。 - DPM
是的。真的。我误读了问题。 - jgauffin
2个回答

3
Autoboxing使用享元模式来最小化对象创建(对于Integer的小值)
例如,对于Boolean和Byte,所有可能的值都被缓存。
Java为许多组件使用状态,但是状态机还包括由状态切换的功能。
这里是我使用枚举编写的示例,使用enum

"自动装箱是享元模式的一个例子"... 这不是有点奇怪的措辞和更奇怪的例子吗!?可以说,对于小值的缓存/重用实际上只是相对于自动装箱所做的事情而言的细节。此外,享元模式的目标是节省内存,而自动装箱是节省内存的最后一件事情。我甚至不会提到在默认Java Map中存储整数{键、值}与在Trove TIntIntHashMap中等效存储时的内存浪费。因此,我认为说"自动装箱是享元模式的一个例子"可能有点奇怪。 - TacticalCoder
1
轻量级模式通常只是与函数实际执行的操作相比的细节。这是因为它们被设计为在很大程度上是透明的,即仅出于性能原因而完成。 - Peter Lawrey
使用HashMap和TIntIntHashMap的区别在于条目的组织方式。如果整数被缓存,大小将是相同的。例如,如果您比较TIntArrayList和ArrayList<Integer>用于缓存值。 - Peter Lawrey
1
+1 我更喜欢你重新改写的版本:原来的措辞有点奇怪,这正是我的观点; ) 是的,在32位虚拟机上,如果您只放置-128到127之间的条目,则大小将相同,但我认为这将是一个非常特殊的情况。在64位虚拟机上,即使是最新的Sun虚拟机默认使用压缩指针,它仍然会稍微大一些(如果我没有弄错的话)。但无论如何,这不是我的重点:我只是说“自动装箱是享元模式的一个例子”听起来有点奇怪,我更喜欢你的新编辑方式,+1!: ) - TacticalCoder
Sun/Oracle 64位JVM 6+默认使用压缩引用(除非堆大小为32GB或更大) - Peter Lawrey
Sun/Oracle 64位JVM 6+默认使用压缩引用。自6u23+以来(如果我没记错的话),这也是我写“即使最新的Sun版本默认使用压缩指针”的原因。;) - TacticalCoder

1

我通常使用状态模式来避免条件语句。

而不是使用:

switch (state)
{
    case ParserState.BeforeMethod:
        //do some processing
        break;
    case ParserState.InMethod:
        //do some processing
        break;
}

我可以直接写:

currentState = currentState.process(context);

一个示例类可以看起来像这样

public class SomeClass : ParserState
{
    public ParserState process(IParserContext context)
    {
       //do some proceccing

       if (m_completed)
           return new SomeOtherState();

       return this;
    }

}

即将逻辑移动到小类中,这些小类用于处理特定状态。因此,您将获得两个好处:
  • 更小的类具有明确的职责
  • 较少的条件语句=更易读的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接