说明
记录下学习设计模式-享元模式的写法。JDK使用版本为1.8版本。
Flyweight(享元)
意图:运用共享技术有效地支持大量细粒度的对象。
结构:
其中:
- Flyweight描述一个接口,通过这个接口Flyweight可以接受并作用于外部状态。
- ConcreteFlyweight实现Flyweight接口,并为内部状态(如果有)增加存储空间。ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的,即它必须独立于ConcreteFlyweight对象的场景。
- 并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。
- FlyweightFactory创建并管理Flyweight对象;确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者在不存在时创建一个实例。
- Client维持一个对Flyweight的引用:计算或存储一个或多个Flyweight的外部状态。
适用性:
- 一个应用程序使用了大量的对象。
- 完全由于使用大量的对象,造成很大的存储开销。
- 对象的大多数状态都可变为外部状态。
- 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
- 应用程序不依赖于对象标识。由于Flyweight对象可以被共享,所以对于概念上明显有别的对象,标识测试将返回真值。
使用场景:
- 一个系统有大量相同或者相似的对象,造成内存的大量耗费。
- 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
- 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,应当在需要多次重复使用享元对象时才值得使用享元模式。
目录
享元模式示例类图
以该UML类图实现享元模式示例。
抽象图形类
package com.example.deesign_patterns.flyweight;
//抽象享元角色
public abstract class AbstractBox {
//获取图形的方法
public abstract String getShape();
//显示图形及颜色
public void display(String color){
System.out.println("方块形状:"+getShape()+",方块颜色:"+color);
}
}
I图形类
package com.example.deesign_patterns.flyweight;
//I图形类(具体享元角色)
public class IBox extends AbstractBox{
@Override
public String getShape() {
return "I";
}
}
L图形类
package com.example.deesign_patterns.flyweight;
//L图形类(具体享元角色)
public class LBox extends AbstractBox{
@Override
public String getShape() {
return "L";
}
}
O图形类
package com.example.deesign_patterns.flyweight;
//O图形类(具体享元角色)
public class OBox extends AbstractBox{
@Override
public String getShape() {
return "O";
}
}
工厂类
package com.example.deesign_patterns.flyweight;
import java.util.HashMap;
//工厂类,将该类设计为单例
public class BoxFactory {
private HashMap<String,AbstractBox> map;
//使用单例模式-饿汉式静态成员变量方式
private static BoxFactory factory=new BoxFactory();
//在构造方法中进行初始化操作
public BoxFactory() {
map=new HashMap<String,AbstractBox>();
map.put("I",new IBox());
map.put("L",new LBox());
map.put("O",new OBox());
}
//提供一个方法获取该工厂类对象
public static BoxFactory getInstance(){
return factory;
}
//根据名称获取图形对象
public AbstractBox getShape(String name){
return map.get(name);
}
}
测试类
package com.example.deesign_patterns.flyweight;
//测试类
public class Client {
public static void main(String[] args) {
//获取I图形对象
AbstractBox box1 = BoxFactory.getInstance().getShape("I");
box1.display("灰色");
//获取L图形对象
AbstractBox box2 = BoxFactory.getInstance().getShape("L");
box2.display("绿色");
//获取O图形对象
AbstractBox box3 = BoxFactory.getInstance().getShape("O");
box3.display("灰色");
//获取O图形对象
AbstractBox box4 = BoxFactory.getInstance().getShape("O");
box4.display("红色");
System.out.println("两次获取到的O图形对象是否是同一个对象:"+(box3==box4));
}
}
好处:文章来源:https://www.toymoban.com/news/detail-500281.html
- 极大减少内存中相似或相同对象数量,节约系统资源,提供系统性能。
- 享元模式中的外部状态相对独立,且不影响内部状态。
缺点:
为了使对象可以共享,需要将享元对象的部分状态外部化,分离内部状态和外部状态,使程序逻辑复杂。文章来源地址https://www.toymoban.com/news/detail-500281.html
到了这里,关于设计模式之享元模式笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!