23种常用设计模式之享元模式

前言

本文代码是以BeanCopier为题材实现的,意在给BeanCopier加一层缓存。但是!!!这个做法是多余的,因为BeanCopier自带了缓存功能,由于刚接触BeanCopier不久,所以干了这件傻事,不过代码对于学习享元模式还是可以的,所以贴了出来,但是不可用于实际工作哦。

说明

享元模式(Flyweight Pattern)是一种结构型模式,主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

应用场景

  • 系统中存在大量的相似对象
  • 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份
  • 需要缓冲池的场景

模式特征

角色 说明 举栗
Flyweight 抽象享元角色 简单地说就是一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现 CopierHolder
ConcreteFlyweight 具体享元角色 具体的一个产品类, 实现抽象角色定义的业务. 该角色需要注意的是内部状态处理应该与环境无关,不应该初恋一个操作改变了内部状态,同时修改了外部状态, 这是角色不允许的 SimpleCopierHolder
FlyweightFactory 享元工厂 职责非常简单, 就是构造一个池容器,同时提供从池中获得对象的方法 CopierFactory

代码实现

代码场景:使用BeanCopier工具进行对象属性拷贝,从OriginBean拷贝到TargetBean,(一开始我以为BeanCopier没有缓存,因为没看源码)而且刚学享元模式,所以想通过享元模式给BeanCopier加一层缓存功能,但是刚写完代码,就想到BeanCopier应该是有缓存的,一看源码,果不其然,心里那个气哦T.T
关于BeanCopier可了解
1.封装BeanCopier工具,支持单个对象以及列表拷贝,超高性能简单实用
2.各类对象属性拷贝工具性能测试对比(BeanCopier、BeanUtils、DozerBeanMapper、PropertyUtils)

  • 抽象享元角色
public abstract class CopierHolder {

    //内部状态
    protected BeanCopier beanCopier;

    /**
     * 源对象类型(外部状态)
     */
    protected Class source;

    /**
     * 目标对象类型(外部状态)
     */
    protected Class target;

    public CopierHolder(Class source, Class target) {
        this.source = source;
        this.target = target;
    }

    /**
     * 创建BeanCopier
     */
    public abstract void createCopier();

}
  • 具体享元角色
public class SimpleCopierHolder extends CopierHolder {

    public SimpleCopierHolder(Class source, Class target) {
        super(source, target);
    }

    @Override
    public void createCopier() {
        this.beanCopier = BeanCopier.create(this.source, this.target, false);
    }

}
  • 享元工厂
public class CopierFactory {

    //定义一个容器
    private static Map<Map<Class, Class>, CopierHolder> pool = new HashMap<>();

    //获取BeanCopier
    public static BeanCopier getBeanCopier(Class source, Class target) {
        Map<Class, Class> keyMap = new HashMap<>();
        keyMap.put(source, target);
        CopierHolder copierHolder;
        if (pool.containsKey(keyMap)) {
            copierHolder = pool.get(keyMap);
        } else {
            copierHolder = new SimpleCopierHolder(source, target);
            copierHolder.createCopier();
            pool.put(keyMap, copierHolder);
        }
        return copierHolder.beanCopier;
    }
}
  • 客户端测试
public class Client{
    public static void main(String[] args){
        //函数getBeanCopier就是支持缓存的,如果存在则直接返回,不存在则会进行创建
        BeanCopier copier = CopierFactory.getBeanCopier(OriginBean.class, Target.class);
    }
}

优缺点

优点

大大减少对象的创建,降低系统的内存,使效率提高。

缺点

提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。

原创文章 67 获赞 31 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u012534326/article/details/102986225