您当前的位置: 首页 > 

宝哥大数据

暂无认证

  • 0浏览

    0关注

    1029博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

23种设计模式11---享元模式

宝哥大数据 发布时间:2017-04-02 22:45:54 ,浏览量:0

享元模式 Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意。享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。    顾名思义:共享元对象。如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用创建新的对象。享元模式是为数不多的、只为提升系统性能而生的设计模式。它的主要作用就是复用大对象(重量级对象),以节省内存空间和对象创建时间。 角色

1、Flyweight:享元接口,通过这个接口Flyweight可以接受并作用于外部状态。通过这个接口可以传入外部的状态,在享元对象的方法处理中可能会使用这些外部的数据。 2、ConcreteFlyweight:具体的享元实现对象,必须是共享的,需要封装Flyweight的内部状态。 3、UnshareConcreteFlyweight:非共享的享元实现对象,并不是所有的Flyweight实现对象都需要共享。非共 享的享元实现对象通常是对享元对象的组合对象。 4、FlyweightFactoty:享元工厂,主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口。 5、Client: 享元客户端,主要的工作就是维持一个对Flyweight的引用,计算或存储享元的外部状态,当然这里可访问共享和不共享的Flyweight对象。

一、代码实现 1.1、享元接口
/**
享元接口:通过这个接口,接受并作用于外部状态
通过这个接口可以传入外部状态,在享元的对象方法处理中可能用到这些外部数据
 */
public interface ChessFlyWeight {
    /**
     * 设置棋子的颜色
     * @param color
     */
    void setColor(String color);
    /**
     * 获取棋子的颜色
     * @return
     */
    String getColor();

    void display(Coordinate coordinate);
}
1.2、具体享元对象
/**
具体享元对象: 具体的享元实现对象,必须是共享的,需要封装FlayWeight的内部状态
 */
public class ConcreateChess implements ChessFlyWeight{
    private String color;
    public ConcreateChess(String color) {
        super();
        this.color = color;
    }
    @Override
    public void setColor(String color) {
        this.color = color;
    }
    @Override
    public String getColor() {
        return this.color;
    }
    @Override
    public void display(Coordinate coordinate) {
        System.out.println("棋子的颜色:"+this.color);
        System.out.println("棋子的位置:"+coordinate.getX()+"----"+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 int getY() {
        return y;
    }
}
1.3、享元工厂
import java.util.HashMap;
import java.util.Map;
/**
享元工厂:主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口
 */
public class ChessFlyWeightFactory {
    //享元池
    private static Map map= new HashMap();
    public ChessFlyWeight getChess(String color) {
        if (map.get(color) == null) {
            ChessFlyWeight chessFlyWeight = new  ConcreateChess(color);
            map.put(color, chessFlyWeight);
            return chessFlyWeight;
        }else {
            return map.get(color);
        }
    }
}
1.4、测试
public class Test {
    public static void main(String[] args) {
        ChessFlyWeightFactory chessFlyWeightFactory = new ChessFlyWeightFactory();
        ChessFlyWeight cfw1 = chessFlyWeightFactory.getChess("红色");
        ChessFlyWeight cfw2 = chessFlyWeightFactory.getChess("红色");
        System.out.println(cfw1);
        System.out.println(cfw2);

         System.out.println("增加外部状态的处理===========");
         cfw1.display(new Coordinate(10, 10));
         cfw2.display(new Coordinate(20, 20));

    }
}

输出:
com.chb.k.FlyWeightDesignPattern.ConcreateChess@15db9742
com.chb.k.FlyWeightDesignPattern.ConcreateChess@15db9742
//cfw1和cfw2是同一个对象
增加外部状态的处理===========
棋子的颜色:红色
棋子的位置:10----10
棋子的颜色:红色
棋子的位置:20----20
模式的优缺点   模式的优点       减少对象数量,节省内存空间。   模式的缺点       维护共享对象,需要额外开销。(比如:一个线程来回收垃圾) 思考
模式本质:分离和共享
开发中的应用场景:

享元模式由于其共享的特征,可以在任何“池”中操作,比如:线程池,数据库连接池。

String类的设计也是享元模式。   在JAVA语言中,String类型就是使用了享元模式。String对象是final类型,对象一旦创建就不可改变。在JAVA中字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝。String a=”abc”,其中”abc”就是一个字符串常量。
public class Test {
    public static void main(String[] args) {   
        String a = "abc";
        String b = "abc";
        System.out.println(a==b);
    }
}

//输出结果:
    true
这就说明a和b两个引用都指向了常量池中的同一个字符串常量”abc”。这样的设计避免了在创建N多相同对象时所产生的不必要的大量的资源消耗。
关注
打赏
1587549273
查看更多评论
立即登录/注册

微信扫码登录

0.0398s