(十二)设计模式-享元模式

1、定义

(Flyweight)运用共享技术有效地支持大量细粒度的对象。

2、使用场景

如果要做三个产品展示、三个博客的网站,相当于是六个网站类的实例,每一个网站都需要一个对应的服务器资源,而本质上他们都是同一套代码,如果网站增多,实例也就随着增多,这对服务器的资源浪费得很严重,而且都不是属于高访问量的网站,如果整合到一个网站中,共享其相关的代码和数据,那么对于服务器资源都可以达成共享,减少服务器资源,而对于代码,由于是一份实例,维护和扩展都更加容易。

3、代码结构UML图

在这里插入图片描述
用户:用户 类,用于网站的客户账号,是”网站“类的外部状态
网站:抽象类所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。
网站工厂:一个享元工厂,用来创建并管理Flyweight对象。它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)
具体网站:继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。也可以指那些不需要共享的Flyweight子类。因为Flyweight接口成为可能,因为它并不强制共享。

4、类的实现

(1)、User(用户类,用于网站的客户账号,是"网站"类的外部状态)
public class User {
    private String  name;

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

    public String getName() {
        return name;
    }
}
(2)、Website (网站抽象类)
public abstract class Website {
    public abstract void use(User user);
}
(3)、ConcreteWebsite (具体网站)
public class ConcreteWebsite extends Website {
    private String name="";

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

    @Override
    public void use(User user) {
        System.out.println("网站分类:"+name+" 用户:"+user.getName());
    }
}
(4)、WebsiteFactory (网站工厂类)
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();
    }
}

5、客户端调用

 public static void main(String[] args) {
        WebsiteFactory f = new WebsiteFactory();
        Website fx = f.getWebsiteCategory("产品展示");
        fx.use(new User("小明"));

        Website fx2 = f.getWebsiteCategory("产品展示");
        fx2.use(new User("小王"));

        Website fx3 = f.getWebsiteCategory("产品展示");
        fx3.use(new User("小花"));

        Website fx4 = f.getWebsiteCategory("博客");
        fx4.use(new User("小黑"));

        Website fx5 = f.getWebsiteCategory("博客");
        fx5.use(new User("小吴"));

        Website fx6 = f.getWebsiteCategory("博客");
        fx6.use(new User("小红"));

        System.out.println("获取网站分类总数:" + f.getWebsiteCount());

    }
输出:

在这里插入图片描述

6、总结

享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上相同的,有时候能够大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅度地减少单个实例的数目。
如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多数组对象,此时可以考虑使用享元模式。


参考:《大话设计模式》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值