加载中...
基于原型模式和享元模式完成不同分层POJO之间的数据拷贝
发表于:2021-05-21 | 分类: 设计模式
字数统计: 731 | 阅读时长: 3分钟 | 阅读量:

享元模式

  • 享元
  • 享受,元数据
  • 同一个数据,我就认为是一个元数据,整个系统里这个数据就一份,缓存起来
  • 整个系统对这个数据,全部享受他一个对象实例即可
  • 直接既有内存来缓存一块数据,用享元模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.util.HashMap;
import java.util.Map;

public class FlyweightPatternDemo {

public static void main(String[] args) {
Flyweight flyweight1 = FlyweightFactory.get("对象1");
flyweight1.execute();

Flyweight flyweight2 = FlyweightFactory.get("对象1");
flyweight2.execute();

System.out.println(flyweight1 == flyweight2);
}

public static interface Flyweight {

void execute();
String getName();
void setName(String name);

}

public static class ConcreteFlyweight implements Flyweight {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public ConcreteFlyweight(String name) {
super();
this.name = name;
}

public void execute() {
System.out.println(name + "执行功能逻辑");
}

}

public static class FlyweightFactory {

private static Map<String, Flyweight> cachePool = new HashMap<String, Flyweight>();
//先获取有没有
//有就取出内存里存在的这一份
public static Flyweight get(String name) {
Flyweight flyweight = cachePool.get(name);
if(flyweight == null) {
flyweight = new ConcreteFlyweight(name);
cachePool.put(name, flyweight);
}
return flyweight;
}

}

}

原型模式

  • 原型模式,就是在要拷贝的类里实现一个clone()方法,自己拷贝自己
  • 拷贝的时候,就两个概念,浅拷贝,深拷贝
  • 很多地方要克隆这个对象,不要自己维护克隆的逻辑,即使克隆逻辑修改了,只要在clone()方法里面修改

在做业务的时候,我们有时为了隔离变化,会将DAO查询出来的Entity,和对外提供的DTO隔离开来。大概90%的时候,它们的结构都是类似的,但是我们很不喜欢写很多冗长的b.setF1(a.getF1())这样的代码,于是我们需要BeanCopier来帮助我们。选择Cglib的BeanCopier进行Bean拷贝的理由是,其性能要比Spring的BeanUtils,Apache的BeanUtils和PropertyUtils要好很多,尤其是数据量比较大的情况下。

BeanCopier工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.util.HashMap;
import java.util.Map;

import net.sf.cglib.beans.BeanCopier;

/**
* BeanCopier工具类
* @author suyuan
*
*/
public class BeanCopierUtils {

/**
* BeanCopier缓存
*/
public static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<String, BeanCopier>();

/**
* 将source对象的属性拷贝到target对象中去
* @param source source对象
* @param target target对象
*/
public static void copyProperties(Object source, Object target){
String cacheKey = source.getClass().toString() +
target.getClass().toString();

BeanCopier beanCopier = null;

// 线程1和线程2,同时过来了

if (!beanCopierCacheMap.containsKey(cacheKey)) {
// 两个线程都卡这儿了
// 但是此时线程1先获取到了锁,线程2就等着
synchronized(BeanCopierUtils.class) {
// 线程1进来之后,发现这里还是没有那个BeanCopier实例
// 此时线程2,会发现缓存map中已经有了那个BeanCopier实例了,此时就不会进入if判断内的代码
if(!beanCopierCacheMap.containsKey(cacheKey)) {
// 进入到这里会创建一个BeanCopier实例并且放在缓存map中
beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopierCacheMap.put(cacheKey, beanCopier);
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
}
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}

beanCopier.copy(source, target, null);
}

}

上一篇:
mybatis-plus总结
下一篇:
通用导入
本文目录
本文目录