结构型模式之五——享元模式

本文介绍了享元模式的概念、结构及应用场景。享元模式通过共享技术有效地支持大量细颗粒度对象的复用,减少了对象数量,提高了系统性能。文章还通过网络设备共享的例子详细解释了享元模式的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模式定义

享元模式(Flyweight Pattern):运用共享技术有效地支持大量细颗粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。享元模式是一种对象结构型模式。

模式结构

这里写代码片

  1. Flyweight
    抽象享元类声明一个接口,通过它可以接受并作用于外部状态。在抽象享元类中定义了具体享元类公共的方法,这些方法可以向外界提供享元的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)。

  2. ConcreteFlyweight
    具体享元类实现了抽象享元接口,其实例称为享元对象,在具体享元类中为内部状态提供了存储空间,由于具体享元对象必须是可以共享的,因此它所存储的状态必须是内部的,即它独立存在于自己的环境中。可以结合单例模式来实际具体享元类,为每一个具体享元类提供唯一的享元对象。

  3. UnSharedConcreteFlyweight
    并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类则设计为非共享具有享元类,当需要一个非共享具体享元类的对象时可以直接通过实例化创建;在某些享元模式的层次结构中,非共享具体享元对象还可以将具体享元对象作为子节点。

  4. FlyweightFactory
    享元工厂类用于创建并管理享元对象;它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中,享元池一般设计为一个存储键值对的集合,可以结合工厂模式进行设计;当用户请求一个具体享元对象时,享元工厂提供存储在享元池中已创建的实例或者创建一个新的实例,返回该新建实例并将其存储在享元池中。

享元模式以共享的方式高效地支持大量的细颗粒度对象,享元对象能做到共享的关键是区分内部状态和外部状态。享元模式的核心在于享元工厂类。

实例——无外部状态

很多网络设备都是支持共享的,如交换机、集线器等,多台计算机终端可以连接同一台网络设备,并通过该设备进行数据转发,现用享元模式模拟共享网络设备的设计原理。
实例类图如下所示:
这里写图片描述

public interface NetworkDevice {
    public String getType();
    public void use();
}

public class Switch implements NetworkDevice {
    private String type;

    public Switch(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void use() {
        System.out.println("Linked by switch, type is " + this.type);
    }
}

public class Hub implements NetworkDevice {
    private String type;

    public Switch(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void use() {
        System.out.println("Linked by Hub, type is " + this.type);
    }
}

public class DeviceFactory {
    private ArrayList devices = new ArrayList();
    private int totalTerminal = 0;

    public DeviceFactory() {
        NetworkDevice nd1 = new Switch("Cisco-WS-C2950-24");
        devices.add(nd1);
        NetworkDevice nd2 = new Hub("TP-LINK-HF8M");
        devices.add(nd2);
    }

    public NetworkDevice getNetworkDevice(String type) {
        if (type.equalsIgnoreCase("cisco")) {
            totalTerminal++;
            return (NetworkDevice)devices.get(0);
        }
        else if (type.equalsIgnoreCase("tp") {
            totalTerminal++;
            return (NetworkDevice)devices.get(1);
        }
        else {
            return null;
        }
    }

    public int getTotalDevice() {
        return devices.size();
    }

    public int getTotalTerminal() {
        return totalTerminal;
    }
}   

实例——有外部状态

虽然网络设备可以共享,但是分配给每一个终端计算机的端口是不同的,因此多台计算机虽然可以共享同一个网络设备,但必须使用不同的端口。可以将端口从网络设备中抽取出来作为外部状态,需要时再进行设置。
实例类图如下所示:
这里写图片描述

public interface NetworkDevice {
    public String getType();
    public void use(Port port);
}

public class Switch implements NetworkDevice {
    private String type;

    public Switch(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void use(Port port) {
        System.out.println("Linked by switch, type is " + this.type + "Port is " +                      
                                   port.getPort());
    }
}

public class Hub implements NetworkDevice {
    private String type;

    public Switch(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void use(Port port) {
        System.out.println("Linked by Hub, type is " + this.type + "Port is " +                      
                                   port.getPort());
    }
}

public class DeviceFactory {
    private ArrayList devices = new ArrayList();
    private int totalTerminal = 0;

    public DeviceFactory() {
        NetworkDevice nd1 = new Switch("Cisco-WS-C2950-24");
        devices.add(nd1);
        NetworkDevice nd2 = new Hub("TP-LINK-HF8M");
        devices.add(nd2);
    }

    public NetworkDevice getNetworkDevice(String type) {
        if (type.equalsIgnoreCase("cisco")) {
            totalTerminal++;
            return (NetworkDevice)devices.get(0);
        }
        else if (type.equalsIgnoreCase("tp") {
            totalTerminal++;
            return (NetworkDevice)devices.get(1);
        }
        else {
            return null;
        }
    }

    public int getTotalDevice() {
        return devices.size();
    }

    public int getTotalTerminal() {
        return totalTerminal;
    }
}   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值