设计模式之——flyweight模式

flyweight模式,又叫做享元模式。

顾名思义,享元模式就是共享一个元素。

百度百科 解释为:

享元模式(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。

本次示例就是以一个球的类,作为元素,来展示享元模式的。

  • 球的类
package site.wangxin520.gof.flyweight;

/**
 * 享元模式里面的“元”
 * @author wangXgnaw
 *
 */
public class Ball {
    
    private String name;
    
    //构造函数,传入球的名称
    public Ball(String name){
        this.name=name;
    }
    
    //打球
    public void play(){
        
        System.out.println("打"+name+";");
        
    }
    
}
  • 球的工厂类
package site.wangxin520.gof.flyweight;

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

/**
 * 用一个球类的工厂,用来创造球
 * 因为享元模式就是共享同一个元素嘛,所以在工厂里面
 * @author wangXgnaw
 *
 */
public class BallFactory {

    private static BallFactory ballFactory=new BallFactory();
    
    //用于保存已经创建好了的球类
    private Map<String, Ball> balls;
    
    //私有化构造
    private BallFactory(){
         balls=new HashMap<>();
    }
    
    /**
     * 返回一个实例,这里让球工厂类变成了一个单例类
     * @return BallFactory 返回一个球类工厂
     */
    public static BallFactory getInstance(){
        return ballFactory;
    }
    
    /**
     * 创建一个球
     * @param ballName 球的名称
     * @return Ball 返回一个球类的实例
     */
    public Ball createBall(String ballName){
        //当map里面包含的话,直接返回,省去再创建实例,浪费资源
        if(balls.containsKey(ballName)){
            return balls.get(ballName);
        }
        //如果map里面没有,那么就创建实例,并且保存到map里面,方便下次调用
        Ball ball = new Ball(ballName);
        balls.put(ballName, ball);
        return ball;
    }
    
}
  • 享元模式的测试类
package site.wangxin520.gof.flyweight;

/**
 * 享元模式的测试类
 * 
 * @author wangXgnaw
 *
 */
public class Test {

    public static void main(String[] args) {

        // 原本情况
        //创建一号乒乓球
        Ball football_01=new Ball("乒乓球");
        football_01.play();
        //创建二号乒乓球
        Ball football_02=new Ball("乒乓球");
        football_02.play();
        System.out.println("两个乒乓球是同一个对象么?"+(football_01==football_02));
        
        System.out.println("--------------------------------");

        // 享元模式下
        // 创建工厂
        BallFactory ballFactory = BallFactory.getInstance();
        // 创建一号篮球
        Ball basketBall_01 = ballFactory.createBall("篮球");
        basketBall_01.play();
        // 创建二号篮球
        Ball basketBall_02 = ballFactory.createBall("篮球");
        basketBall_02.play();
        System.out.println("两个篮球是同一个对象么?"+(basketBall_01==basketBall_02));
    }

}
  • 控制台输出为:

image

可见,同样是打球,可是两种获取示例的方式,得到的球的对象却是不一样的!想打球的次数多的话,调用同一个类是一种明智的选择,这样可以节省大量的资源。因为我们都知道,不可能每次打球,都去重新买一个球吧。哈哈哈!

原文地址:https://www.cnblogs.com/wangxinblog/p/7745029.html