Structual设计--Flyweight模式

1.意图

运用共享技术有效地支持大量细粒度的对象。

2.别名

3.动机

有些应用程序得意于在其整个设计过程中采用对象技术,但简单化的实现代价极大。如我们在使用word的时候,如果设置正文字体为:text.setFont(new Font(“細明體”, Style.BOLD, 12));每一个文字我们都需要这样设置,内存太大,而且也非常难记,稍有不注意就会出错。所以通常并不是对每个字符都用一个单独的对象去表示。Flyweight模式描述了如何共享对象,是的可以细粒度地使用他们而无需高昂的代价。

4.适用性

Flyweight模式的有效性很大程度上取决于如何使用它以及在何处使用它。当以下情况都成立时使用Flyweight模式:

  • 一个应用程序使用了大量的对象
  • 完全由于大量的对象,造成很大的存储开销
  • 对象的大多数状态都可变为外部状态。
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
  • 应用程序不依赖于对象标识。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。

5.结构

享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。

FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建一个新对象,FlyWeight是超类。一提到共享池,我们很容易联想到Java里面的JDBC连接池,想想每个连接的特点,我们不难总结出:适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接池来说,url、driverClassName、username、password及dbname,这些属性对于每个连接来说都是一样的,所以就适合用享元模式来处理,建一个工厂类,将上述类似属性作为内部数据,其它的作为外部数据,在方法调用时,当做参数传进来,这样就节省了空间,减少了实例的数量。

看个例子:

6.代码示例

看下数据库连接池的代码:

public class ConnectionPool {

    private Vector<Connection> pool;

    /*公有属性*/
    private String url = "jdbc:mysql://localhost:3306/test";
    private String username = "root";
    private String password = "root";
    private String driverClassName = "com.mysql.jdbc.Driver";

    private int poolSize = 100;
    private static ConnectionPool instance = null;
    Connection conn = null;

    /*构造方法,做一些初始化工作*/
    private ConnectionPool() {
        pool = new Vector<Connection>(poolSize);

        for (int i = 0; i < poolSize; i++) {
            try {
                Class.forName(driverClassName);
                conn = DriverManager.getConnection(url, username, password);
                pool.add(conn);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /* 返回连接到连接池 */
    public synchronized void release() {
        pool.add(conn);
    }

    /* 返回连接池中的一个数据库连接 */
    public synchronized Connection getConnection() {
        if (pool.size() > 0) {
            Connection conn = pool.get(0);
            pool.remove(conn);
            return conn;
        } else {
            return null;
        }
    }
}

通过连接池的管理,实现了数据库连接的共享,不需要每一次都重新创建连接,节省了数据库重新创建的开销,提升了系统的性能!

7.相关模式

  • Flyweight模式通常和Composite模式结合起来,用共享叶结点的有向无环图实现一个逻辑上的层次结构。
  • 通常,最好用Flyweight实现State和Strategy对象。

引用:

http://openhome.cc/Gossip/DesignPattern/DecoratorPattern.htm

http://item.jd.com/10057319.html

http://blog.csdn.net/zhangerqing/article/details/8239539

时间: 2024-10-13 17:01:19

Structual设计--Flyweight模式的相关文章

Structual设计--Adapter模式

1.意图 将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原来由于接口不兼容而不能在一起工作的那些类可以在一起工作. 2.别名 包装器Wrapper. 3.动机 有时,为复用而设计的工具箱类不能够被复用原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配.具体场景可以描述为:基础功能类–>adapter专业接口–>专业调用,其中基础功能类可以理解为我们常见的jdk,也可以是一些sdk或者一些平台支持类. 4.适用性 以下情况使用Adapter模式 你想使用一个已经存在的类,而

Structual设计--Composite模式

1.意图 将对象组合成树形结构以表示"部分-整体"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 2.别名 无 3.动机 在绘图编辑器和图形捕捉系统这样的图形应用程序中,用户可以使用简单的组件创建复杂的图表.用户可以组合多个简单组件以形成一些较大的组件,这些组件又可以组合成更大的组件.一个简单的实现方法是为Text和Line这样的图元定义一些类,另外定义一些类作为这些图元的容器类(Container). 然而存在一个问题:使用这些类的代码必需区别对待图元对

Structual设计--Proxy 模式

1.意图 为其他对象提供一种代理以控制对这个对象的访问. 2.别名 Surrogate 3.动机 对一个对象进行访问控制的一个愿意是为了只有在我们确实需要这个对象时才对他进行创建和初始化.譬如手机上加载图片,每一个屏幕的大小是有限定的,我们无需每次把所有图片都加载上,只有在需要展示的时候才对图片进行创建和初始化. 4.适用性 在需要用比较通用和复杂的对象指针代理简单的指针的时候,使用Proxy.下面是一些可以使用Proxy模式常见的情况: 远程代理(Remote Proxy)为一个对象在不同的地

Structual设计--Bridge模式

1.意图 将抽象部分与它的实现部分分离,使他们都可以独立地变化. 2.别名 Handle/Body 3.动机 当一个抽象对象可能有多个实现时,通常用继承来协调它们.抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现.但是此方法有时不够灵活.继承机制将抽象部分与它的实现部分固定在一起,使得难以对抽象部分和实现部分独立的进行修改.扩充和重用. 4.适用性 以下情况使用Bridge模式: 你不希望在抽象和它的实现部分之间有一个固定的绑定关系.例如这种情况可能是因为,在程序运行时刻实现部分应可以

Structual设计--Facade模式

1.意图 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层的接口,这个接口使得这一子系统更加容易使用. 2.别名 无 3.动机 将一个系统划成为若干个子系统有利于降低系统的复杂性.一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小.达到该目标的途径之一是引入一个外观(facade)对象,它为子系统中较一般的设施提供了一个单一而简单的界面.例如算法库有很多算法类,我们在使用的时候分别去调用,最后算法库的外部调用和算法之间的关系会变的错综复杂,这就需要我们引入facad

Structual设计--Decorator 模式

1.意图 动态的给一个对象添加额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 2.别名 包装器Wrapper. 3.动机 有时,我们希望给某个对象而不是整个类添加一些功能.例如,肯德基推出特价套餐,如果套餐1中有:汉堡和鸡腿和价格,套餐二中有:薯条和汉堡和价格,如果做继承类,而且是多继承明显不够灵活,那么就需要装饰类. 4.适用性 以下情况使用Decorator模式 在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职责. 处理他那些可以撤销的职责. 当不能采用

Flyweight模式(亨元模式)

这应该算是最好理解的一个设计模式了吧·················· 面向对象语言的原则就是一切都是对象,但是如果真正使用起来,有时对象数可能显得很庞大,比如,字处理软件,如果以每个文字都作为一个对象,几千个字,对象数就是几千,无疑耗费内存,那么我们还是要"求同存异",找出这些对象群的共同点,设计一个元类,封装可以被共享的类,另外,还有一些特性是取决于应用(context),是不可共享的,这也是Flyweight中两个重要概念--内部状态intrinsic和外部状态extrinsi

Flyweight模式详解--设计模式(9)

Flyweight模式产生原因: 在面向对象系统的设计何实现中,创建对象是最为常见的操作.这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销.特别是对于大量轻量级(细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为没有字母创建一个对象的话,系统可能会因为大量的对象而造成存储开销的浪费.例如一个字母"a"在文档中出现了100000次,而实际上我们可以让这一万个字母"a"共享一个对象,当然因为在不同的位置可能字母"a"

Java共享模式/享元模式(Flyweight模式)

Flyweight定义:避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类). 为什么使用共享模式/享元模式 面向对象语言的原则就是一切都是对象,但是如果真正使用起来,有时对象数可能显得很庞大,比如,字处理软件,如果以每个文字都作为一个对象,几千个字,对象数就是几千,无疑耗费内存,那么我们还是要"求同存异",找出这些对象群的共同点,设计一个元类,封装可以被共享的类,另外,还有一些特性是取决于应用(context),是不可共享的,这也Flyweight中两个重要概念内