享元模式在主流的标准里是放到结构大类下的,但我感觉这个模式的最终作用也是为了获取一个类,所以我将其划分到创建大类下。方便我理解一点。
享元模式主要是用于减少创建对象的数量,以节省内存和提高性能。它通过共享对象来支持大量细粒度对象的高效使用。
核心思想
- 共享对象: 将可共享的部分抽取出来,只保留不变的部分。
 - 内部状态: 可以共享的状态,存储在享元对象内部。
 - 外部状态: 不能共享的状态,由客户端维护。
 
工作原理
- 享元工厂: 负责创建和管理享元对象,确保共享对象的复用。
 - 对象复用: 如果一个对象已经存在,直接返回它;否则创建一个新对象。
 
适用场景
- 需要大量创建相似对象时。
 - 内存使用是系统的主要问题时。
 
优点
- 降低内存消耗。
 - 提高性能。
 
缺点
- 使系统逻辑更加复杂。
 - 需要分离内部和外部状态,增加了使用的难度。
 
What is Flyweight Pattern
Flyweight 是指轻量级的。
享元模式旨在支持大量细粒度的对象共享,以减少内存消耗。该模式通过共享相似对象的部分状态,来减少对象的数量。通过共享,可以节省内存并提高系统的性能。
享元模式通常涉及两个关键概念:
- 内部状态(Intrinsic State)
内部状态是可以共享的部分,存储在享元对象内部; - 外部状态(Extrinsic State)
外部状态是不可共享的部分,需要在使用时提供。 
通过将内部状态与外部状态分离,可以实现对象的共享。享元模式适用于需要创建大量相似对象且内存消耗较大的场景。
Think:
这个模式给我最大的启发就是,一些大量且要耗费大量资源,即使它本身是一个整体,也要考虑继续将它细分,更细粒度的管控它,这个细分的手段就是设置一个状态。 这个思想也广泛的运用在IT的各个领域,比如说>>TODO。
Q:享元模式是通过在类里面设置状态,达到控制类的目的吗?
A:不完全正确。享元模式是一种结构设计模式,其主要目的是通过共享对象来减少内存使用和提高性能。它通过将对象的状态划分为内部状态(Intrinsic State)和外部状态(Extrinsic State)来实现。
内部状态是可以被多个对象共享的状态,它不依赖于具体的场景或上下文,可以在多个对象之间共享和复用。而外部状态是随着具体的场景或上下文变化的状态,它不能被共享,需要在使用时传递给享元对象。
通过将内部状态和外部状态分离,享元模式可以大幅减少系统中对象的数量,从而节省内存空间。而通过传递外部状态,可以使得享元对象在不同的场景中具有不同的行为,从而实现灵活性。
因此,尽管享元模式可以通过内部状态和外部状态的设置来控制类的行为,但其核心目的并不是通过状态的设置来控制类,而是通过共享对象和分离状态来提高内存利用和性能。
Comparison between prototype and Flyweight
Similarities:
- 从场景上来看都是为了节省资源区创建大量相似的对象;
 - 一般都是配合工厂模式;
 
Differences:
- Flyweight 如果需要创建不同的对象,就得提供不同的外部状态;
 - Prototype 无需依赖于显式的构造函数,它通过复制现有对象的原型来创建新对象。
 
Key Elements
- 享元类接口
 - 享元类实现
 - 获取享元类工厂
 
Example 1
在绘制大量相同形状但颜色不同的图形时,可以使用享元模式来共享形状对象,只改变颜色这种外部状态。这样可以显著减少内存使用。
Example 2
当你使用享元模式时,你需要定义一个享元工厂(Flyweight Factory),它负责创建和管理享元对象。下面是一个简单的Java代码示例,演示了如何实现享元模式:
首先,我们定义享元接口(Flyweight):
public interface Flyweight {
    void operation();
}
然后,实现具体的享元类(ConcreteFlyweight):
public class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;
    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }
    @Override
    public void operation() {
        System.out.println("ConcreteFlyweight: " + intrinsicState);
    }
}
接下来,创建享元工厂类(FlyweightFactory)来管理享元对象:
import java.util.HashMap;
import java.util.Map;
public class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();
    public Flyweight getFlyweight(String key) {
        if (flyweights.containsKey(key)) {
            return flyweights.get(key);
        } else {
            Flyweight flyweight = new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
            return flyweight;
        }
    }
}
最后,我们可以使用享元工厂来获取享元对象并调用其方法:
public class Main {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1 = factory.getFlyweight("A");
        flyweight1.operation();
        Flyweight flyweight2 = factory.getFlyweight("B");
        flyweight2.operation();
        Flyweight flyweight3 = factory.getFlyweight("A");
        flyweight3.operation();
        // 输出结果:
        // ConcreteFlyweight: A
        // ConcreteFlyweight: B
        // ConcreteFlyweight: A
    }
}
在上述示例中,我们使用享元工厂来获取享元对象。首次获取某个享元对象时,工厂会创建一个新的对象并将其存储在内部的HashMap中。之后,如果再次请求相同的享元对象,则直接返回已经创建的对象。这样就实现了对象的共享,减少了内存消耗。
希望这个简单的示例能帮助你理解享元模式的基本概念和用法。
                    
                
                
            
        
浙公网安备 33010602011771号