享元模式(FlyWeight)----设计模式
享元模式,主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式是什么?
享元模式,享即共享,元即对象,享元模式通俗的理解就是通过特定的手段实现对多次使用的对象进行共享,达到减少内存的占用和提高性能。
嘿嘿,是不是听着有些像单例模式呢,其实不是的,单例模式是共享的只有一个对象,而享元模式是共享的多个只有一个实例的对象,这些实例都有相同的状态特征。
享元模式的结构
一般来说,实现享元模式需要以下几个部分实现:
-
Flyweight抽象类
所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。 -
ConcreteFlyweight类
继承Flyweight超类或实现Flyweight接口,并为其内部状态增加存储空间。 -
FlyweightFactory类
一个享元工厂,用来创建并管理Flyweight对象,主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或创建一个实例。 -
Client客户端
用于进行测试操作的类。 -
外部状态的类(如User类)
在享元模式中,一般分为内部状态与外部状态。内部状态即为可以共享的部分,外部状态指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态。 -
原理类图
案例演示
假如现在有一个网站上的文章,现在要以新闻、博客、微信小程序等渠道进行发布,但是阅读这些文章的用户不仅仅一个人,而且阅读的渠道也各有不同,所以我们没有必要为每一个用户创建一个网站或博客等,我们只根据用户的具体使用情况为其创造一种渠道即可,供其他用户共享。
实现步骤
通过在享元工厂定义一个集合,实现对象池的技术,若用户需要具体的一种对象,先判断池中是否存在,若存在,直接从对象池中取出使用即可;若不存在,则对此对象进行创建,并添加到对象池中方便使用。
代码演示
享元类的父类WebSite
package com.design_patterns.flyweight;
//享元类的父类WebSite
public abstract class WebSite {
//定义抽象方法
public abstract void use(User user);
}
具体享元类ConcreteWebSite
package com.design_patterns.flyweight;
public class ConcreteWebSite extends WebSite {
private String type = ""; //网站发布的形式(类型)
private User user = null;
//构造方法
public ConcreteWebSite(String type){
this.type = type;
}
@Override
public void use(User user) {
setUser(user);
System.out.println("网站发布的形式为" + type +
"---->使用者(" + user.getName() + ")");
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
享元工厂类WebSiteFactory
package com.design_patterns.flyweight;
import java.util.HashMap;
/**
* 网站工厂类, 根据需求返回一个具体的网站
*/
public class WebSiteFactory {
private HashMap<String,ConcreteWebSite> pool = new HashMap<String, ConcreteWebSite>();
/**
* 根据网站的类型,返回一个网站,如果没有就创建一个网站,并放入到池中,并返回
* @param type
* @return
*/
public WebSite getWebSiteCategory(String type){
if(!pool.containsKey(type)){
//就创建一个网站,并将其放入池中
pool.put(type,new ConcreteWebSite(type));
}
return (WebSite)pool.get(type);
}
/**
* 获取网站分类的总数
* (池中有多少个网站类型)
* @return
*/
public int getWebSiteCount(){
return pool.size();
}
}
外部状态类User
package com.design_patterns.flyweight;
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;
}
}
测试类客户端Client
package com.design_patterns.flyweight;
public class Client {
public static void main(String[] args) {
//创建一个工厂
WebSiteFactory webSiteFactory = new WebSiteFactory();
//客户要一个以新闻形式发布的网站
WebSite webSite = webSiteFactory.getWebSiteCategory("新闻");
//客户要一个以博客形式发布的网站
WebSite webSite1 = webSiteFactory.getWebSiteCategory("博客");
//客户要一个以博客形式发布的网站
WebSite webSite2 = webSiteFactory.getWebSiteCategory("博客");
//客户要一个以微信小程序形式发布的网站
WebSite webSite3 = webSiteFactory.getWebSiteCategory("微信小程序");
//客户要一个以微信小程序形式发布的网站
WebSite webSite4 = webSiteFactory.getWebSiteCategory("微信小程序");
//客户要一个以微信小程序形式发布的网站
WebSite webSite5 = webSiteFactory.getWebSiteCategory("微信小程序");
webSite.use(new User("Tom"));
webSite1.use(new User("tom"));
webSite2.use(new User("Jack"));
webSite3.use(new User("jack"));
webSite4.use(new User("HaHa"));
webSite5.use(new User("XiXi"));
System.out.println("\n网站的分类共---->" + webSiteFactory.getWebSiteCount() + "个");
}
}
总结
享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。
好啦,进行共享内部的状态,区别独立的外部状态,这就是享元模式,小伙伴们加油呀~~~