本篇来讨论下java设计模式之享元模式。

享元,很奇怪的名词。 就像编程界,很多奇怪的名词,比如析构函数(万恶的c++),鲁棒性(robust,叫稳健就好,粗俗的就是耐操【文明】)。 反正我一开始是没看懂,经过网上的各路大神的解释,享元,共享元素,就是一种解决过多的对象的问题,可能他们实际对外部来说都是一样的特性,可以直接重复使用,再加上一些自己的东西。

以共享的方式高效的支持大量的细粒度对象。

这话说的好高深。不管了。 talk is cheap,show me the code。 code_gun 你看,我需要提取一个抽象的特征,比如吧,一个通信工具,能够具有什么核心功能呢?必须能够打电话啊!不管你是烧狼粪的,还是用qq的,还是打电话。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package top.txiner.flyweight;

/**
 * @author : hundred
 * time: 18-1-17
 * website : http://txiner.top
 * 懵懂的小白
 */
public interface Device {
    void dial();
}

为了区分不同的东西,正经点,我们都理解成手机系列吧。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class Phone implements Device {
    private String brand;

    public Phone(String brand) {
        this.brand = brand;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    @Override
    public void dial() {
        System.out.println("My brand is "+brand+" and I can dial");
    }
}

然后来个造手机的厂子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class DeviceFactory {
    private static Map<String,Device> deviceMap=new HashMap<>();

    public static Device getDevice(String brand){
        if (deviceMap.containsKey(brand)){
            return deviceMap.get(brand);
        }else {
            Device device=new Phone(brand);
            deviceMap.put(brand,device);
            return device;
        }
    }
}

好了,可以打电话了

1
2
3
4
5
6
7
8
9
public class User {
    public static void main(String[] args) {
        Device samsung=DeviceFactory.getDevice("samsung");
        Device phone=DeviceFactory.getDevice("samsung");
        samsung.dial();
        System.out.println(phone==samsung);
        System.out.println(DeviceFactory.getSize());
    }
}

我们会很清楚的发现,使用的实际上是同一个共同变量。 有问题了,有时候并不是这一个通信工具,有个土豪,有好多手机。一个就不够了。怎么办? 那就组合出来!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class CompositePhone implements Device{

    private Map<String,Device> labels=new HashMap<>();

    public void add(String brand,Device device){
        labels.put(brand,device);
    }

    @Override
    public void dial() {
        for (Object brand:labels.keySet()){
            labels.get(brand).dial();
        }
    }
}

我们也得改变造手机的厂子。

1
2
3
4
5
6
7
public static Device getCompositeDevice(List<String> brands){
        CompositePhone device=new CompositePhone();
        for (String brand:brands){
            device.add(brand,getDevice(brand));
        }
        return device;
    }

再看土豪怎么做的吧。

1
2
3
4
5
6
List<String> phones=new ArrayList<>();
        phones.add("samsung");
        phones.add("oneplus");
        phones.add("huawei");
        Device tuhao=DeviceFactory.getCompositeDevice(phones);
        tuhao.dial();

问题得解! ....................分割线................ 这个跟我们之前接触过的很相似,但是并不是同一个。还需要具体对比下。