享元模式

要开发的小项目

 

 

 

 

 

 

 

 

传统方案解决网站展示项目-问题分析

 

 

 

享元模式基本介绍

 

 

 

享元模式的原理类图

 

 

 

内部状态和外部状态

 

 

 

 

享元模式应用实例

 

 

 

 

 

 

类图:

以上是仅仅是享元模式的内部状态

package com.flyweight;

public abstract class WebSite {
    public abstract void use();//抽象方法
}

 

package com.flyweight;

/**
 * 具体网站
 */
public class ConcreteWebSite extends WebSite {

    //共享的部分,内部状态
    private String type = "";//网站发布的形式

    //构造器
    public ConcreteWebSite(String type) {
        this.type = type;
    }

    @Override
    public void use() {

        System.out.println("网站的发布形式为:"+type+" ,正在使用中。。。");
    }
}

 

package com.flyweight;

import java.util.HashMap;
import java.util.Map;

/**
 * 网站工厂类,根据需要返回一个网站
 */
public class WebSiteFactory {
    //创建一个集合,充当池的作用
    private Map<String ,ConcreteWebSite> pool = new HashMap<>();

    public WebSite getWebSiteCategory(String type){
        if(!pool.containsKey(type)){
            //如果池中没有,就创建一个网站,并放入到池中
            pool.put(type,new ConcreteWebSite(type));
        }
        return (WebSite)pool.get(type);
    }

    //获取网站分类的总数(池中有多少个网站类型)
    public int getWebSiteCount(){
        return pool.size();
    }
}

 

package com.flyweight;


public class Client {
    public static void main(String[] args) {

        //创建一个工厂类
        WebSiteFactory factory = new WebSiteFactory();

        //客户要一个以新闻形式发布的网站
        WebSite webSite1 = factory.getWebSiteCategory("新闻");
        webSite1.use();
        //客户要一个以博客形式发布的网站
        WebSite webSite2 = factory.getWebSiteCategory("博客");
        webSite2.use();
        //客户要一个以博客形式发布的网站
        WebSite webSite3 = factory.getWebSiteCategory("博客");
        webSite3.use();
        //客户要一个以博客形式发布的网站
        WebSite webSite4 = factory.getWebSiteCategory("博客");
        webSite4.use();
        System.out.println("网站工厂中一共有"+factory.getWebSiteCount()+"个实例");
    }
}

 

运行结果:

网站的发布形式为:新闻 ,正在使用中。。。

网站的发布形式为:博客 ,正在使用中。。。

网站的发布形式为:博客 ,正在使用中。。。

网站的发布形式为:博客 ,正在使用中。。。

网站工厂中一共有2个实例

 

接下来我们对上面的代码进行简单地修改,添加上享元模式的外部状态

 

 代码实现:

package com.flyweight;

public abstract class WebSite {
    public abstract void use(User user);//抽象方法
}

 

package com.flyweight;

/**
 * 具体网站
 */
public class ConcreteWebSite extends WebSite {

    //共享的部分,内部状态
    private String type = "";//网站发布的形式

    //构造器
    public ConcreteWebSite(String type) {
        this.type = type;
    }

    @Override
    public void use(User user) {

        System.out.println("网站的发布形式为:"+type+" ,正在使用中。。。使用者是:"+user.getName());
    }
}

 

package com.flyweight;

import javax.swing.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 网站工厂类,根据需要返回一个网站
 */
public class WebSiteFactory {
    //创建一个集合,充当池的作用
    private Map<String ,ConcreteWebSite> pool = new HashMap<>();

    public WebSite getWebSiteCategory(String type){
        if(!pool.containsKey(type)){
            //如果池中没有,就创建一个网站,并放入到池中
            pool.put(type,new ConcreteWebSite(type));
        }
        return (WebSite)pool.get(type);
    }

    //获取网站分类的总数(池中有多少个网站类型)
    public int getWebSiteCount(){
        return pool.size();
    }
}

 

package com.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;
    }
}

 

package com.flyweight;


public class Client {
    public static void main(String[] args) {

        //创建一个工厂类
        WebSiteFactory factory = new WebSiteFactory();

        //客户要一个以新闻形式发布的网站
        WebSite webSite1 = factory.getWebSiteCategory("新闻");
        webSite1.use(new User("Tom"));
        //客户要一个以博客形式发布的网站
        WebSite webSite2 = factory.getWebSiteCategory("博客");
        webSite2.use(new User("jack"));
        //客户要一个以博客形式发布的网站
        WebSite webSite3 = factory.getWebSiteCategory("博客");
        webSite3.use(new User("amy"));
        //客户要一个以博客形式发布的网站
        WebSite webSite4 = factory.getWebSiteCategory("博客");
        webSite4.use(new User("smith"));
        System.out.println("网站工厂中一共有"+factory.getWebSiteCount()+"个实例");
    }
}

 

运行结果:

网站的发布形式为:新闻 ,正在使用中。。。使用者是:Tom

网站的发布形式为:博客 ,正在使用中。。。使用者是:jack

网站的发布形式为:博客 ,正在使用中。。。使用者是:amy

网站的发布形式为:博客 ,正在使用中。。。使用者是:smith

网站工厂中一共有2个实例

 

享元模式在JDK-Integer的应用源码分析

 

 

 

package com.flyweight;

public class FlyWeightTest {
    public static void main(String[] args) {
        //如果 Integer.valueOf(x) x 在 -128 --- 127 直接,就是使用享元模式返回,如果不在范围内,则仍然 new
        //小结:
        //1. 在 valueOf 方法中,先判断值是否在 IntegerCache 中,如果不在,就创建新的 Integer(new), 否则,就直接从缓存池返回
        //2. valueOf 方法,就使用到享元模式
        //3. 如果使用 valueOf 方法得到一个 Integer 实例,范围在 -128 - 127 ,执行速度比 new 快
        Integer x = Integer.valueOf(127); // 得到 x实例,类型 Integer
        Integer y = new Integer(127); // 得到 y 实例,类型 Integer
        Integer z = Integer.valueOf(127);//..
        Integer w = new Integer(127);
        System.out.println(x.equals(y)); // 大小,true
        System.out.println(x == y ); // false
        System.out.println(x == z ); // true
        System.out.println(w == x ); // false
        System.out.println(w == y ); // false
        Integer x1 = Integer.valueOf(200);
        Integer x2 = Integer.valueOf(200);
        System.out.println("x1==x2:" + (x1 == x2)); // false
    }
}

 

运行结果:

true

false

true

false

false

x1==x2false

posted on 2022-05-08 10:25  ~码铃薯~  阅读(64)  评论(0编辑  收藏  举报

导航