栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

结构型设计模式----享元模式FlyWeight

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

结构型设计模式----享元模式FlyWeight

闲话

今天是周末,本来想偷一下懒,想想还是看一节设计模式吧
写的不好,欢迎大家一起讨论~

基本要点

1、使用场景:内存属于稀缺资源,如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存

2、核心
–以共享的方式支持大量细粒度对象的重用

–享元对象能做到共享的关键是区分了内部状态和外部状态
内部状态:可以共享,不会随环境变化而改变
外部状态:不可以共享,会随环境变化而改变

举例围棋软件来说
每个棋子都可以看成一个对象,颜色、形状、大小都能称为内部状态,因为这些是可共享的
但是位置每一个棋子都是独一无二的,是不可共享的,所以是外部状态

3、享元模式的实现
–FlyweightFactory享元工厂类:创建并管理享元对象,享元池一般设计成键值对(可以理解为Map)
–FlyWeight抽象享元对象:通常是一个接口或抽象类,用于声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态,例子中的棋子就可以看成这个
–ConcreteFlyWeight具体享元类:将内部状态放在这,为内部状态提供成员变量进行存储
–UnsharedConcreteFlyWeight非共享享元类:将外部状态放在这,不能被共享的子类可以设计成非共享享元类

4、享元模式优缺点
优点:极大减少了内存中对象的数量,节约系统资源,而且外部状态相对独立,不影响内部状态。
缺点:模式较为复杂,使程序逻辑复杂化;为了节省内存,共享了内部状态,分离出了外部状态,而读取外部状态时间较长,为了空间牺牲了时间。

实现代码

我们以上面的围棋系统为例子
首先,我们创建享元类和具体享元类

public interface ChessFlyWeight {
    // 获取棋子颜色(获取内部状态)
    String getColor();

    // 设置棋子坐标(设置外部状态)
    void display(Coordinate coordinate);
}


class ChessConcreteFlyWeight implements ChessFlyWeight {
    // 为内部状态提供成员变量进行存储
    private String color;

    public ChessConcreteFlyWeight(String color) {
        this.color = color;
    }

    @Override
    public String getColor() {
        return color;
    }

    @Override
    public void display(Coordinate coordinate) {
        System.out.println("棋子颜色:" + color);
        System.out.println("棋子坐标:x= " + coordinate.getX() + "y=" + coordinate.getY());
    }
}

创建非共享享元类,将外部状态放在这里

public class Coordinate {
    // 棋子的坐标是外部状态
    private int x,y;

    public Coordinate(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

创建享元工厂

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


public class ChessFlyWeightFactory {
    // 享元池
    private static Map map = new HashMap();

    // 根据颜色获取棋子对象
    public static ChessFlyWeight getChess(String color) {
        // 如果有符合当前颜色要求的棋子对象,那就返回
        if (null != map.get(color)) {
            return map.get(color);
        } else {
            // 如果没有符合的对象就创建新的棋子对象,然后将其放入享元池中,在返回
            ChessFlyWeight chess = new ChessConcreteFlyWeight(color);
            map.put(color, chess);
            return chess;
        }
    }
}

模拟客户端

public class Client {
    public static void main(String[] args) {
        ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
        ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
        // chess1创建时,享元池里面并没有黑色棋子,所以创建了一个,获取chess2时,有了黑色棋子,所以可以直接去拿之前创建的那个对象
        System.out.println(chess1);
        System.out.println(chess2);

        System.out.println("增加外部状态处理===========");
        chess1.display(new Coordinate(10, 10));
        chess2.display(new Coordinate(20, 20));
    }
}

运行结果如图

如有错误,欢迎指正

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605483.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号