23种设计模式之享元模式

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

(Flyweight Pattern)

结构型设计模式

通过共享技术,避免相同细粒度对象的重复创建。

享元模式可以避免大量非常相似类的开销。在程序设计中,有时候需要生成大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数外基本相同,就能将这些不相同的参数移出类外,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。


介绍

意图: 运用共享技术有效地支持大量细粒度的对象。(缓存内部状态)

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

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

核心角色:

  • 抽象享元角色(Flyweight): 享元对象抽象基类或者接口,同时定义出对象的外部状态和内部状态的接口或实现。
  • 具体享元角色(ConcreteFlyweight):实现抽象角色定义的业务。该角色的内部状态处理应该与环境有关,不能出现有一个操作改变内部状态,同时修改了外部状态。
  • 享元工厂(FlyweightFactory): 负责管理享元对象池和创建享元对象。

主要代码: 内部状态和外部状态的划分

何时使用:

  • 系统中有大量的重复对象
  • 这些对象消耗大量的内存
  • 这些对象的状态大部分可以内部化
  • 这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。
  • 系统不依赖于这些对象身份,这些对象是不可分辨的。

1. 代码实现

我们先来看一段没有使用享元模式的代码

abstract class Phone{
 public abstract void Use();   
}
class NokiaPhone extend Phone{
    private String phoneType;
    //手机中的服务
    private String serverIp;
    private String serverPort;
    private String serverConf;
    //手机号码和外观
    private String phoneNumber;
    private String phoneAppearance;
    
    public NokiaPhone(String phoneType,String serverIp,String serverPort,String phoneNumber){
        this.phoneType = phoneType;
        this.serverIp = serverIp;
        this.serverPort = serverPort;
        this.phoneNumber = phoneNumber;
    }
    
    @Override
    public void user(){
        sout("serverIp"+serverIp);
        sout("serverPort"+serverPort);
        sout("serverConf"+serverConf);
        sout("call:phoneNumebr"+ this.phoneNumber)
    }
}

可以看到,我们每次想要调用use方法时,都会给里面的IP,port,等信息重复赋值。同一个手机的型号,他的服务器配置信息都是相同的,接下来我们通过享元模式,将一个大的对象进行细粒度的划分。



abstract class Phone{
 public abstract void Use(UnShardProperties unShardProperties);   
}
class NokiaPhone extend Phone{
	private String phoneType;
    //手机中的服务
  	private NetworkService networkService; // 服务器配置信息(Shard)
    
    //手机号码和外观
    private UnShardProperties unShardProperties; //不共享的配置信息
    
    public NokiaPhone(String phoneType){
        //这里假设手机连接网络的服务配置都是相同的,所以可以从缓存的代码处,取出直接赋值即可
        this.networkService = defaultNetworkService;
        this.phoneType = phoneType;
    }
    
    @Override
    public void user(UnShardProperties unShardProperties){
        sout("serverIp"+networkService.getServerIp());
        sout("serverPort"+networkService.getServerPort());
        sout("serverConf"+networkService.getServerConf();
        sout("call:phoneNumebr"+ unShardProperties.getPhoneNumber())
    }
}
             
class PhoneFactory{
    private Map<String,Phone> cacheMap = new HashMap<String, Phone>();
    
    public Phone getPhone(String key){
        if (!cacheMap.containsKey(key)){
            cacheMap.put(key,new Phone(key))
        }
        return cacheMap.get(key);
    }
}

class FlyweightPatternDemo{
	psvm{
		PhoneFactory factory = new PhoneFactory();
		Phnoe phone = factory.getPhone("NOkia E66666666");
		phone.use(new UnShardProperties("133233XXXXX","red"));
	}
}
注意看上方细粒度的提取(不会随环境改变而改变的共享部分抽取为内部状态)。
享元模式也可以看作是对象的部分数据做缓存操作,继而重复使用。

2. 享元设计模式的内部状态和外部状态

2.1 什么是内部状态?

在享元对象内部并且不会随环境改变而改变的共享部分。

2.2 什么是外部状态?

而随外部环境改变而改变的就是外部状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王叮咚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值