设计模式——享元模式

一、使用场景

在程序设计过程中,有时需要创建大量或相似的对象实例,创建这么多的对象将耗费更多的系统资源。需要将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,从而降低内存的消耗。

二、享元模式

运用共享技术来有效地支持大量细度对象的复用。通过共享已经存在的对象来大幅度减少需要创建的对象数量,避免大量相似对象的开销,从而提高系统资源的利用率。

享元模式存在两种状态:

    1)内部状态,不会随着环境改变而改变的可共享部分;

        2)外部状态,随环境改变而改变的不可共享部分;

享元模式一般结合工厂模式一起使用,主要角色有:

1)抽象享元角色,通常是一个接口或抽象类,声明享元类公共的方法,这些方法可向外界提供享元对象的内部结构,同时也可以通过这些方法设置外部状态;

2)具体享元,为内部状态提供存储空间,通常可以结合单例模式来设计具体享元类,为每个具体享元提供唯一的享元对象;

3)享元工厂,负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

图 享元模式UML图

需求描述:某出租车公司名下有多辆出租车,公司需要统计每辆车每天的总里程、及乘客数量。

public class FlyweightTest {

    static abstract class Taxi {

        protected int id; //汽车编号

        protected int mileage; //总里程
        protected int passengerNum; //乘客数量

        /**
         * 载客
         * @param num 乘客数量
         * @param mileage 里程
         */
        public abstract void carryPassenger(int num, int mileage);

    }

    static class RealTaxi extends Taxi {

        public RealTaxi(Integer id) {
            this.id = id;
        }

        @Override
        public void carryPassenger(int num, int mileage) {
            this.passengerNum += num;
            this.mileage += mileage;
        }

        @Override
        public String toString() {
            return "RealTaxi{" +
                    "id=" + id +
                    ", mileage=" + mileage +
                    ", passengerNum=" + passengerNum +
                    '}';
        }
    }

    static class TaxiFactory {

        private TaxiFactory() {}

        private static Map<Integer,Taxi> taxiMap = new HashMap<>();

        /**
         * 派车
         * @param id 汽车编号
         * @return 出租车
         */
        public static Taxi sendCar(Integer id) {
            Taxi taxi = taxiMap.get(id);
            if (taxi == null) {
                taxi = new RealTaxi(id);
                taxiMap.put(id,taxi);
            }
            return taxi;
        }

        /**
         * 数据统计
         */
        public static void statistics() {
            Set<Integer> keySet = taxiMap.keySet();
            Iterator<Integer> iterator = keySet.iterator();
            while (iterator.hasNext()) {
                Integer id = iterator.next();
                Taxi taxi = taxiMap.get(id);
                System.out.println(taxi);
            }
        }

    }

    public static void main(String[] args) {
        Random random = new Random(12);
        for (int i = 0; i < 24; i++) {
            Taxi taxi = TaxiFactory.sendCar(random.nextInt(5));//总共5辆车,编号从0到4
            taxi.carryPassenger(random.nextInt(3) + 1, random.nextInt(10));//载客
        }
        TaxiFactory.statistics();
    }
    
//    运行结果:
//    RealTaxi{id=0, mileage=14, passengerNum=14}
//    RealTaxi{id=1, mileage=33, passengerNum=14}
//    RealTaxi{id=2, mileage=14, passengerNum=3}
//    RealTaxi{id=3, mileage=24, passengerNum=9}
//    RealTaxi{id=4, mileage=15, passengerNum=10}

}

2.1 优缺点

优点:1)极大减少内存中相同或相似对象的数量,节约系统资源;2)享元模式中外部状态相对独立,且不影响内部状态;

缺点:享元对象分为内部状态和外部状态,使程序逻辑变得复杂;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值