Flyweight:享元
角色
Flyweight 抽象的享元角色, Website
ConcreteFlyWeight(内部状态) 具体的享元角色 BlogWebSite NewsWebSite 这个是必须聚合到享元工厂
UnSharedConcreteFlyWeight(外部状态) 不可共享的角色,一般不会出现在享元工厂 这个是非必要的角色,视需求而定
FlyWeightFactory 享元工厂类,用于构建一个池容器(集合), 同时提供从池中获取对象方法 WebsiteFactory
案例
需求:项目外包案例;
给客户A做了一个产品展示网站,客户A的朋友觉得效果不错,也需要一个类似的网站,但是运营的内容有所不同;
具体需求:客户ABC三个客户要拿来展示博客,客户DEF三个客户要拿来展示新闻,客户GHL三个客户要拿来展示电影...
使用前
按照常规的逻辑来思考,ABCDEFGHL九个客户要求开发相同结构的网站,运营不同的网站,那么我们将只要将这个结构的网站做出来,打成jar包,复制九份部署到九个客户的服务器中,让客户查看项目展示效果即可;
这就相当于工厂类创建出九个网站实例出来就可以了
代码如下
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.javaxl.design.flyweight.before;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-23 19:50
*/
public class WebSite {
private String contentType;
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public WebSite(String contentType) {
this.contentType = contentType;
}
public void use(User user) {
System.out.println(user.getName() + "要求开发" + this.contentType);
}
}
class WebSiteFactory {
public static WebSite createWebSite(String contentType) {
return new WebSite(contentType);
}
}
public class Client {
public static void main(String[] args) {
WebSite webSite1 = WebSiteFactory.createWebSite("博客网站");
WebSite webSite2 = WebSiteFactory.createWebSite("博客网站");
WebSite webSite3 = WebSiteFactory.createWebSite("博客网站");
webSite1.use(new User("客户A"));
webSite2.use(new User("客户B"));
webSite3.use(new User("客户C"));
System.out.println(webSite1.hashCode());
System.out.println(webSite2.hashCode());
System.out.println(webSite3.hashCode());
System.out.println("==================");
WebSite webSite4 = WebSiteFactory.createWebSite("新闻网站");
WebSite webSite5 = WebSiteFactory.createWebSite("新闻网站");
WebSite webSite6 = WebSiteFactory.createWebSite("新闻网站");
webSite4.use(new User("客户D"));
webSite5.use(new User("客户E"));
webSite6.use(new User("客户F"));
WebSite webSite7 = WebSiteFactory.createWebSite("电影网站");
WebSite webSite8 = WebSiteFactory.createWebSite("电影网站");
WebSite webSite9 = WebSiteFactory.createWebSite("电影网站");
webSite7.use(new User("客户G"));
webSite8.use(new User("客户H"));
webSite9.use(new User("客户L"));
}
}
我们可以让客户ABC,看部署在同一台服务器上的博客网站的展示效果;
享元模式(蝇量模式)干的就是这么一件事情。
使用后
UML类图
class WebSiteFactory {
static HashMap<String, WebSite> webSiteMap = new HashMap();
public static WebSite createWebSite(String contentType) {
WebSite webSite = webSiteMap.get(contentType);
if (webSite == null) {
webSite = new WebSite(contentType);
webSiteMap.put(contentType, webSite);
}
return webSite;
}
}
结果:相同开发需求的客户,共享了同一个服务器来验收网站展示效果;
上面的是借助享元模式的思想进行类结构设计,但不是标准的享元模式结构;
标准的享元模式UML类图如下
注意事项及细节
大大减少了对象的创建,降低了程序内存的占用,提高效率
用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象,用 HashMap/HashTable 存储
使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制
注意:享元模式提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变
应用
字符串常量池
数据库连接池
缓冲池
JDK源码中Integer类的valueOf
新一代虚拟化技术Docker
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有