Head First设计模式<二>:享元模式

1 介绍

享元模式主要用于减少对象的数量,以减少内存占用性和提高性能。这种类型的设计模式属于结构型模型,他提供了减少对象数量从而改善应用所需的对象结构的方式。(概念ps:来自百度)
意图:享元模式就是用共享技术有效的支持大量细粒度对象的复用。减少对象的重复创建,实现对象的多个复用功能。
两个概念:内部状态,外部状态。这个是我们学习享元模式必须要知道的重要点之一。
内部状态:我们在享元对象内部定义的成员,不会因为外部环境的改变而改变,内部状态只做对象功能的定义。内部状态是被共享的状态。
外部状态:随着外部环境的改变而改变,我们需要使用共享状态来实现不同的功能效果,这个不被共享的状态就是外部状态。
 
关于使用:
    1: 系统中有大量的对象。
    2:这些对象消耗大量内存。
    3:这些对象的状态大部分可以外部化,内部状态可以实现共享。
 

2 模式结构:

不多哔哔了,上个结构图给大家凑合看一下,我们就开始撸代码。
 

3 设计实现:

步骤一:创建一个鸭子的共享功能接口:
 1 package com.alibaba.Flyweight;
 2 
 3 /**
 4  * 鸭子群
 5  *
 6  * @author Mr.Tk
 7  * @date 2019/3/09 14:30
 8  */
 9 public interface Ducks {
10 
11     /**
12      * 游泳
13      */
14     void swim();
15 }

 

步骤二:再来一个鸭子的共享内部状态
 1 package com.alibaba.Flyweight.impl;
 2 
 3 import com.alibaba.Flyweight.Ducks;
 4 
 5 /**
 6  * 鸭子实例
 7  *
 8  * @author Mr.Tk
 9  * @date 2019/3/09 14:33
10  */
11 public class Duck implements Ducks {
12 
13     //鸭子品种
14     private String name;
15 
16     //飞行技能
17     private String fly;
18 
19     //叫声
20     private String quack;
21 
22     //鸭子颜色
23     private String color;
24 
25     public Duck(String name) {
26         this.name = name;
27     }
28 
29     public void setColor(String color) {
30         this.color = color;
31     }
32 
33     public void setFly(String fly) {
34         this.fly = fly;
35     }
36 
37     public void setQuack(String quack) {
38         this.quack = quack;
39     }
40 
41     @Override
42     public void swim() {
43         System.out.println("门前大桥下游过一只鸭。。。"
44             + "color:" + color + "  name:" + name + "  fly:" + fly + "  quack:" + quack);
45     }
46 }

 

步骤三:享元工厂和享元池的创建

package com.alibaba.Flyweight;

import com.alibaba.Flyweight.impl.Duck;

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

/**
 * 鸭子的享元工厂
 *
 * @author Mr.Tk
 * @date 2019/3/09 14:47
 */
public class DuckFactory {

    /**
     * 工厂内部维护的享元池
     */
    private static final Map<String, Duck> map = new HashMap<>();

    /**
     * 工厂可以选择自己制造鸭子的方法入参方式,我这里为了方便观看选择参数入参, 实际使用中可以选择对象入参避免参数过多代码可读性降低。
     *
     * @return Duck
     */
    public static Duck getDuck(String name) {
        Duck duck = (Duck)map.get(name);
        if (null == duck) {
            duck = new Duck(name);
            map.put(name, duck);
            System.out.println("鸭子品种 --> " + name);
        }
        return duck;
    }
}

 

步骤四:模拟一下实现

 1 package com.alibaba.strategy;
 2 
 3 import com.alibaba.Flyweight.DuckFactory;
 4 import com.alibaba.Flyweight.impl.Duck;
 5 
 6 public class Test {
 7 
 8     private static final String names[] = {"Red鸭子", "yellow鸭子", "木头鸭子", "99鸭"};
 9 
10     public static void main(String[] args) {
11         //颜色
12         String colors[] = {"红色", "绿色", "黄色", "麻辣色"};
13         //飞行
14         String flys[] = {"展翅高飞", "不会飞", "躺着飞"};
15         //叫声
16         String quacks[] = {"嗷嗷叫", "吱吱叫", "不会叫"};
17 
18         /************************   享元模式  ***********************************/
19         for (int i = 0; i < 10; i++) {
20             Duck duck = DuckFactory.getDuck(names[(int)(Math.random() * names.length)]);
21             duck.setColor(colors[(int)(Math.random() * colors.length)]);
22             duck.setFly(flys[(int)(Math.random() * flys.length)]);
23             duck.setQuack(quacks[(int)(Math.random() * quacks.length)]);
24             duck.swim();
25         }
26     }
27 }

 

看下运行结果:
 
 

4 总结

   4.1 优点
      1 :享元模式能够极大的减少系统中对象的个数。
      2:享元模式由于使用的外部状态,外部状态相对独立,不会影响到内部状态,所以享元对象能够在不同的环境被共享使用。
 
   4.2 缺点
      1:由于享元模式需要区分外部状态和内部状态,使得程序再一定程度上被复杂化。
      2:为了使对象可以被共享,享元模式需要将享元对象的状态外部化,外部状态的增加使得程序读取运行的时间变长。
 

posted @ 2019-03-09 16:47  Mr·Tangke  阅读(178)  评论(0编辑  收藏  举报