zoukankan      html  css  js  c++  java
  • 设计模式笔记之十一 (享元模式)

    享元模式

    享元模式的英文说法是:Flyweight Parrern, 又被译作蝇量模式。这两种译法分别说明了其需要解决的问题,解决问题的方式:

    当我们需要解决许多轻量类引起的资源开销问题的时候(蝇量模式),我们可以用重用共同点的元素(享元模式)的方法来解决。

    正如我们实验室最近接到的一个订单的最终解决方案一样。

    前段时间我们的太阳市场部得到一笔大订单:太阳国某富豪要举办一场盛大的聚会,他们需要订购一批女人来满足他的客人们:

    class NvRen {
        private String name;
        private String head;
        private String body;
        private String type;
    
        public NvRen(String name, String head, String body, String type) {
            this.name = name;
            this.head = head;
            this.body = body;
            this.type = type;
        }
    
        public void service() {
            System.out.println("服务者:" + this.name);
        }
    }
    
    public class FlyWeight {
        public static void main(String[] args) {
            int customerNumber = 1000;
            String customer = "客人";
            for (int i = 0; i < customerNumber; i++) {
                String customerName = customer + i;
                System.out.print("客人: " + customerName + " 的");
                new NvRen("松岛" + i + "子", "瓜子脸", "葫芦型", "气质高雅型").service();
            }
        }
    }

    但是当我们准备生产的时候,有个对太阳国比较有研究的技术宅说,据他的了解,在太阳国就算再富有的富豪也找不出一套房子来容纳1000个客人,如果再加上我们的1000个女人产品,肯定连站的地方都没有,更别说躺下或者趴下了。

    我们一想也是,到时候那个富豪别一看放不下这么多的人而不定我们的产品了,那就比较尴尬了。

    于是我们想到既然没有那么多的地方来容纳那么多的"女人",我们可以少生产一点,反正也没有同时提供service的地方。于是一个新的解决方案出炉了,就是我们提供一个小黑屋,里面只有一个"女人",但是服务不同客户的时候报不同的名字:

    class NvRen {
        private String name;
        private String head;
        private String body;
        private String type;
    
        public NvRen(String name, String head, String body, String type) {
            this.name = name;
            this.head = head;
            this.body = body;
            this.type = type;
        }
    
        public void service(String name) {
            System.out.println("服务者:" + name);
        }
    }
    
    class BlackRoom { // 单例的小黑屋
        private static BlackRoom br;
        private static final Object o = new Object();
        private static NvRen nr;
    
        private BlackRoom() {
            nr = new NvRen("", "瓜子脸", "葫芦型", "气质高雅型"); // 小黑屋里面只有一个女人的实例
        }
    
        public static BlackRoom getInstance() {
            if (br == null) {
                synchronized (o) {
                    if (br == null) {
                        br = new BlackRoom();
                    }
                }
            }
            return br;
        }
    
        public void service(int i) {
            String name = "松岛" + i + "子";
            nr.service(name);// 小黑屋里面的女人在提供service的时候报不同的名字
        }
    }
    
    public class FlyWeight {
        public static void main(String[] args) {
            int customerNumber = 1000;
            String customer = "客人";
            for (int i = 0; i < customerNumber; i++) {
                String customerName = customer + i;
                System.out.print("客人: " + customerName + " 的");
                BlackRoom.getInstance().service(i);
            }
        }
    }

    现在我们只要造一个"女人"就能满足富豪的需求了,而且不会因为地方不够而担心了。

    当然,最终我们提供给客户的时候当然不是这么简单的单个产品,我们会提供好几种不同的女人来满足不同客人的需求:

    import java.util.HashMap;
    
    class NvRen {
        private String name;
        private String head;
        private String body;
        private String type;
    
        public NvRen(String name, String head, String body, String type) {
            this.name = name;
            this.head = head;
            this.body = body;
            this.type = type;
        }
    
        public void service(String name) {
            System.out.println("服务者:" + name + "(真实的女人编码:" + this.hashCode() + ")");
        }
    }
    
    class BlackRoom { // 单例的小黑屋
        private static BlackRoom br;
        private static final Object o = new Object();
        private static HashMap<String, NvRen> nrs = new HashMap<String, NvRen>();
    
        private BlackRoom() {
            // 供客人使用的几种类型
            nrs.put("类型1", new NvRen("", "瓜子脸", "葫芦型", "气质高雅型"));
            nrs.put("类型2", new NvRen("", "圆脸", "葫芦型", "邻家少女型"));
            nrs.put("类型3", new NvRen("", "圆脸脸", "纤细型", "萝莉型"));
            nrs.put("类型4", new NvRen("", "瓜子脸", "葫芦型", "御姐型"));
            // 专供主人使用的女主人
            nrs.put("女主人", new NvRen("", "面饼脸", "纺锤型", "屠夫型"));// 女主人是不共享的
        }
    
        public static BlackRoom getInstance() {
            if (br == null) {
                synchronized (o) {
                    if (br == null) {
                        br = new BlackRoom();
                    }
                }
            }
            return br;
        }
    
        public void service(Integer i) {
            String name = "";
            String type = "";
            if (i != null) {
                name = "松岛" + i + "子";
                type = "类型" + (Math.round(Math.random() * 3) + 1);
            } else {
                name = "女主人";
                type = "女主人";
            }
            nrs.get(type).service(name); // 小黑屋里面的女人在提供service的时候报不同的名字
        }
    }
    
    public class FlyWeight {
        public static void main(String[] args) {
            // 1000个客人
            int customerNumber = 1000;
            String customer = "客人";
            for (int i = 0; i < customerNumber; i++) {
                String customerName = customer + i;
                System.out.print(customerName + "的");
                BlackRoom.getInstance().service(i);
            }
    
            System.out.print("主人的");
            // 主人
            BlackRoom.getInstance().service(null);
        }
    }

    以上就是一个享元模式的应用。当然由于这个模式应用的非常少(本人还没有在项目中用到过),所以如有不当的地方请斧正。

  • 相关阅读:
    poj1459(多源点网络流)
    poj 2480
    poj1850和poj1496(组合数)
    poj3252(组合数)
    hdu1452(逆元)
    因子和与因子个数
    poj 2478(欧拉函数打表)
    p3807(lucas定理)
    F-有趣的数字(组合数+逆元)
    《Java并发编程的艺术》Java并发机制的底层实现原理(二)
  • 原文地址:https://www.cnblogs.com/biglaojiang/p/3090846.html
Copyright © 2011-2022 走看看