设计模式->结构型模式->享元模式

来源:互联网 发布:网络信息安全漫画 编辑:程序博客网 时间:2024/05/23 20:49

1.定义:该模式是池技术的基础,运用共享对象有效的支持大量细粒度对象

细粒度对象该对象的性质基本相同或者相似且对象很多

将细粒度对象分为两部分

1.1内部状态

存储在享元对象内部的,并且不会随着环境的改变而改变,一个享元可以具有内蕴状态并可以共享。

1.2外部状态

是随环境的改变而改变的、不可以共享的。享元对象的外部状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外部状态不可以影响享元对象的内部状态,它们是相互独立的。也就是说接受外部状态后处理对应的逻辑但是不允许修改享元的内部状态。

2.UML

单纯享元模式:结合中的每个对象都是可以共享的


3.涉及角色:

        抽象享元角色:定义享元行为以及必要的内部状态以及外部状态以及对外部状态的接受。该角色中可以没有内部状态只有行为

        具体享元角色:抽象享元角色的实现。该角色实现具体的逻辑

享元工厂:负责创建具体的享元角色。客户端不能直接通过具体的享元角色穿件对象。因为这样最新创建的角色无法存贮。导致后续的无法复用现有的对象

4.优点

1.减少对象创建,降低内存占有率,增强程序性能

2.复用现有对象

5.缺点

1.增加系统复杂性因为对象需要区分外部状态和内部状态

2.内部状态固化不应该随着外部状态的变化而变化。否则将会导致系统结构混乱以及池混乱

6.使用场景

        1.系统中存在大量的性质相近的对象

        2.细粒度对象都具备相近的外部状态,且内部状态和环境无关。

3.需要缓冲池的应用

7.Code

//抽象享元

public abstract class Flyweight {    //内部状态    private String innerStatus;    //外部状态,定义为final防止意外修改    protected final String externalStatus;    //通过构造函数接受外部状态,强制子类接受外部状态也可在使用外部状态的行为中以参数的形式传入    public Flyweight(String externalStatus) {        this.externalStatus = externalStatus;    }    public String getInnerStatus() {        return innerStatus;    }    public void setInnerStatus(String innerStatus) {        this.innerStatus = innerStatus;    }    //定义行为    public abstract void outputStatus();}

//具体享元

public class ConcreteFlyweight extends Flyweight {    //子类接受外部状态    public ConcreteFlyweight(String externalStatus) {        super(externalStatus);    }    //外部状态接受成功后按照具体的逻辑执行业务    @Override    public void outputStatus() {        //TODO 执行业务逻辑        System.out.println("innerStatus:" + super.getInnerStatus() + ", externalStatus: " + externalStatus);    }}

享元工厂

public class FlyweightFactory {    private static Map<String, Flyweight> map = new HashMap<String, Flyweight>();    public static Flyweight getFlyweight(String externalStatus) {        if(map.containsKey(externalStatus)) {            return map.get(externalStatus);        } else {            Flyweight flyweight = new ConcreteFlyweight(externalStatus);            map.put(externalStatus, flyweight);            return flyweight;        }    }    //测试多次获得对象后集合长度,测试方法    public static int getMapSize() {        return map.size();    }}

客户端

public class Client {    public static void main(String[] args) {        Flyweight f1 = FlyweightFactory.getFlyweight("f1");        f1.setInnerStatus("f1");        f1.outputStatus();        Flyweight f2 = FlyweightFactory.getFlyweight("f2");        f2.setInnerStatus("f2");        f2.outputStatus();        Flyweight f3 = FlyweightFactory.getFlyweight("f3");        f3.setInnerStatus("f3");        f3.outputStatus();        Flyweight f4 = FlyweightFactory.getFlyweight("f2");        f4.setInnerStatus("f2");        f4.outputStatus();        System.out.println(FlyweightFactory.getMapSize());    }}