首页 > 代码库 > 享元模式

享元模式

享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。

在享元对象内部并且不会随环境改变而改变的共享部分,可以称为是享元对象的内部状态,而随环境改变而改变的、不可以共享的状态就是外部状态。

享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够受大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。

享元模式应用:如果一个应用程序用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

字符串String 就运用享元模式,两个字符串是相同的实例。

String a ="abc",String b="abc"

围墙、五子棋、跳棋,它们都有大量的棋子对象,围棋、五子棋只有黑白两色、跳棋颜色略微多一些,但也是不太变化的,所以颜色应该是棋子的内部状态;而各个棋子之间的主要就是位置的不同,所以方位坐标就是应该棋子的外部状态。

User类

package FlyWeight;
/**
 * 专门的类处理外部状态
 * 不同的博客、产品展示是客户不一样
 * 所以客户就是外部状态
 * @author 煞笔
 *
 */
public class User {
    private Long id;
    private String name;
    
    public User(Long id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
}
Website 
package FlyWeight;

public abstract class Website {
    public abstract void show(User user);
}

ShareWebsite类

package FlyWeight;
/**
 * 需要共享的对象,来降低内存的损耗
 * 在享元对象内部,并且不会随环境改变
 * 处理内部状态
 * @author 煞笔
 *
 */
public class ShareWebsite extends Website {
    private String type;
    
    public ShareWebsite(String type) {
        super();
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public void show(User user) {
        System.out.println("欢迎"+user.getName()+"登录"+type);
    }

}

WebsiteFactory类

package FlyWeight;

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

/**
 * 创建并管理共享网站对象的工厂
 * @author 煞笔
 *
 */
public class WebsiteFactory {
    public Map<String,ShareWebsite> websites = new HashMap<String,ShareWebsite>();
    public ShareWebsite getWebsite(String type){
        if(websites.containsKey(type)){
            return websites.get(type);
        }else{
            ShareWebsite website = new ShareWebsite(type);
            websites.put(type, website);
            return website;
        }
    }
    public int getWebsiteCount(){
        return websites.size();
    }
}

UnShareWebsite类

package FlyWeight;
/**
 * 不需要共享的对象
 * @author 煞笔
 *
 */
public class UnShareWebsite extends Website {

    @Override
    public void show(User user) {
        System.out.println("用户"+user.getName()+"的独特的内容");
    }

}

Business类

package FlyWeight;

public class Business {
    public static void main(String[] args){
        WebsiteFactory factory = new WebsiteFactory();
        ShareWebsite bk1 = factory.getWebsite("博客");
        bk1.show(new User(1L,"大A"));
        ShareWebsite bk2 = factory.getWebsite("博客");
        bk2.show(new User(2L,"大B"));
        ShareWebsite bk3 = factory.getWebsite("博客");
        bk3.show(new User(3L,"大C"));
        ShareWebsite cp1 = factory.getWebsite("产品展示");
        cp1.show(new User(4L,"品A"));
        ShareWebsite cp2 = factory.getWebsite("产品展示");
        cp2.show(new User(5L,"品B"));
        ShareWebsite cp3 = factory.getWebsite("产品展示");
        cp3.show(new User(6L,"品C"));
        System.out.println("网站分类数目:"+factory.getWebsiteCount());
        UnShareWebsite unws = new UnShareWebsite();
        unws.show(new User(7L,"不一般"));
    }
}

欢迎大A登录博客
欢迎大B登录博客
欢迎大C登录博客
欢迎品A登录产品展示
欢迎品B登录产品展示
欢迎品C登录产品展示
网站分类数目:2(就只有两个实例)
用户不一般的独特的内容

 

享元模式