• 享元模式


    要开发的小项目

     

     

     

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

    享元模式基本介绍

    享元模式的原理类图

     

    内部状态和外部状态

    享元模式应用实例

     

    类图:

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

    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

  • 相关阅读:
    exe自启动的几种方式
    关于 CShellManager 的作用
    DLL 调用 对话框 以及 如何获取调用dll 应用程序(窗口程序)的窗口句柄
    VC++ 2010 创建高级Ribbon界面详解(4)
    HPU--1221 Fibonacci数列
    取一个数的前几位
    HDU--1875 畅通工程再续
    POJ--2485 Highways
    【模板】HDU--1233 畅通工程
    hdu--1856 More is better
  • 原文地址:https://www.cnblogs.com/dongyaotou/p/16244943.html
Copyright © 2020-2023  润新知