设计模式——享元模式

享元模式

1、概念

1)解决场景

需要在系统中增加类和对象个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。

2)概念

享元模式(Flyweight Pattern)又称轻量级模式,是对象池的一种实现。类似于线程池,线程池可以不停的创建和销毁多个对象,消耗性能。提供了减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细颗粒度对象,将多个对同一对象的访问几种起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。

3)原理

享元模式把一个对象的状态分成内部状态和外部状态,内部状态即是不变的,外部状态是变化的;然后通过共享不变的部分,达到减少对象数量并节约内存的目的。
享元模式的本质是缓存共享对象,降低内存消耗。

4)角色

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

5)内部状态和外部状态

享元模式的定义为我们提出了两个要求:细粒度和共享对象。因为要求细粒度对象 ,所以不可避免地会使对象数量多且性质相近 ,此时我们就将这些对象的信息分为两个部分:内部状态和外部状态。
内部状态指对象共享出来的信息 ,存储在享元对象内部并且不会随环境的改变而改变;外部状态指对象得以依赖的一个标记 ,是随环境改变而改变的、不可共享的状态。
比如 ,连接池中的连接对象 ,保存在连接对象中的用户名、密码、连接url等信息 ,在创建对象的时候就设置好了 ,不会随环境的改变而改变 ,这些为内部状态。而每个连接要回收利用时 ,我们需要给它标记为可用状态 ,这些为外部状态。

2、使用

1)代码实现

抽象享元角色(IFlyweight)

package com.csk.mode.flyweightPattern.domain;

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
package com.csk.mode.flyweightPattern.service;

import com.csk.mode.flyweightPattern.domain.User;

public interface WebSite {
    void use(User user);
}
具体享元角色(ConcreteFlyweight)
package com.csk.mode.flyweightPattern.service.impl;

import com.csk.mode.flyweightPattern.domain.User;
import com.csk.mode.flyweightPattern.service.WebSite;

public class ConcreteWebSite implements WebSite {
    private String name = "";

    public ConcreteWebSite(String name) {
        this.name = name;
    }

    @Override
    public void use(User user) {
        System.out.println("网站分类: "  + name + ";用户:" + user.getName());
    }
}
享元工厂(FlyweightFactory)
package com.csk.mode.flyweightPattern.factory;

import com.csk.mode.flyweightPattern.service.WebSite;
import com.csk.mode.flyweightPattern.service.impl.ConcreteWebSite;

import java.util.Hashtable;

public class WebSiteFactory {
    private Hashtable flyweights = new Hashtable();

    // 获得网站分类
    public WebSite getWebSiteCategory(String key){
        if(!flyweights.containsKey(key)){
            flyweights.put(key, new ConcreteWebSite(key));
        }
        return (WebSite) flyweights.get(key);
    }

    // 获取网站分类总数
    public int getWebSiteCount(){
        return flyweights.size();
    }
}
启动类
package com.csk.mode.flyweightPattern.controller;

import com.csk.mode.flyweightPattern.domain.User;
import com.csk.mode.flyweightPattern.factory.WebSiteFactory;
import com.csk.mode.flyweightPattern.service.WebSite;

public class FlyweightPatternMain {
    public static void main(String[] args) {
        WebSiteFactory webSiteFactory = new WebSiteFactory();
        WebSite fx = webSiteFactory.getWebSiteCategory("产品展示");
        fx.use(new User("雨哥"));

        WebSite fy = webSiteFactory.getWebSiteCategory("产品展示");
        fy.use(new User("旭哥"));

        WebSite fz = webSiteFactory.getWebSiteCategory("产品展示");
        fz.use(new User("凯哥"));

        WebSite fl = webSiteFactory.getWebSiteCategory("博客");
        fl.use(new User("刘雨"));

        WebSite fm = webSiteFactory.getWebSiteCategory("博客");
        fm.use(new User("张旭策"));

        WebSite fn = webSiteFactory.getWebSiteCategory("博客");
        fn.use(new User("陈书凯"));

        System.out.println("网站分类总数为:" + webSiteFactory.getWebSiteCount());
    }
}
截图

在这里插入图片描述

2)使用场景

常常应用于系统底层的开发,以便解决系统的性能问题;
系统有大量相似的对象、需要缓存池的场景;

3)优缺点

优点

减少对象的创建 ,降低内存中对象的数量 ,降低系统的内存 ,提高效率;减少内存之外的其它资源占用。

缺点

关注内、外部状态、关注线程安全问题;使系统、程序复杂化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值