问题引入:
编写一个程序实现,不同类型网站内容的具体输出
源代码:
package org.zangyu.share;
public class share {
public static void main(String[] args) {
// TODO Auto-generated method stub
website web1= new website("产品展示");web1.Use();
website web2= new website("产品展示");web2.Use();
website web3= new website("产品展示");web3.Use();
website web4= new website("博客");web4.Use();
website web5= new website("博客");web5.Use();
website web6= new website("博客");web6.Use();
}
}
class website{
private String name;
public website(String name) {
this.name=name;
}
public void Use() {
System.out.println("网站分类"+"\t"+name);
}
}
资源浪费严重,总体就两种网站类型,博客和产品展示,可实现资源共享
运用享元模式
享元模式
基本框架
package org.zangyu.Flyweight;
import java.util.HashMap;
public class flyweight10 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String extrinsic="22";
flyweightfactory f=new flyweightfactory();
flyweight2 flyweightx = f.getflyweight("x");
flyweightx.operate(extrinsic);
flyweight2 flyweighty = f.getflyweight("x");
flyweighty.operate("23");
flyweight2 flyweightz = f.getflyweight("x");
flyweightz.operate("24");
flyweight2 unshare= new unsharedconcreteflyweight("X");
unshare.operate(extrinsic);
}
}
abstract class flyweight2{
public String intrinsic;//内部状态
protected String extrinsic;//外部状态
public flyweight2(String extrinsic) {
//要求共享角色必须接收外部状态
this.extrinsic=extrinsic;
}
public abstract void operate(String extrinsic);//定义业务操作
public String getintrinsic() {
return intrinsic;
}
public void setintrinsic(String intrinsic) {
this.intrinsic=intrinsic;
}
}
class concreteflyweight extends flyweight2{
//接收外部状态
public concreteflyweight(String extrinsic) {
super(extrinsic);
// TODO Auto-generated constructor stub
}
//根据外部状态进行逻辑处理
@Override
public void operate(String extrinsic) {
// TODO Auto-generated method stub
System.out.println("具体flyweight"+extrinsic);
}
}
class flyweightfactory{
//定义一个池容器
private static HashMap<String,flyweight2> pool =new HashMap<String,flyweight2>();
//享元工厂
public static flyweight2 getflyweight(String extrinsic) {
flyweight2 flyweight=null;
if(pool.containsKey(extrinsic)) {//池中有该对象
flyweight=pool.get(extrinsic);
System.out.println("已有"+extrinsic+"直接从池中取出---");
}else {//根据外部状态创建享元对象
flyweight = new concreteflyweight(extrinsic);
pool.put(extrinsic, flyweight);//放入池中
System.out.println("创建"+extrinsic+"从池中取出---");
}
return flyweight;
}
}
class unsharedconcreteflyweight extends flyweight2{
public unsharedconcreteflyweight(String extrinsic) {
super(extrinsic);
// TODO Auto-generated constructor stub
}
@Override
public void operate(String extrinsic) {
// TODO Auto-generated method stub
System.out.println("不共享的具体flyweight"+extrinsic);
}
}
具体实例
用享元模式实现网站共享
源代码:(不含外部状态)
package org.zangyu.Flyweight;
import java.util.HashMap;
public class flyweight20 {
public static void main(String[] args) {
// TODO Auto-generated method stub
websitefactory f= new websitefactory();
website web1 = f.getwebsite("产品展示");
web1.Use();
website web2 = f.getwebsite("产品展示");
web2.Use();
website web3 = f.getwebsite("产品展示");
web3.Use();
website web4 = f.getwebsite("博客");
web4.Use();
website web5 = f.getwebsite("博客");
web5.Use();
website web6 = f.getwebsite("博客");
web6.Use();
System.out.println("网站分类总数"+f.getwebsitecount());
}
}
abstract class website{
public abstract void Use();
}
class concretewebsite extends website{
private String name;
public concretewebsite(String name) {
this.name=name;
}
@Override
public void Use() {
// TODO Auto-generated method stub
System.out.println("网站分类:"+name);
}
}
class websitefactory{
private static HashMap<String,website>flyweights=new HashMap<String,website>();
//获得该网站分类
public website getwebsite(String key)
{
if(!flyweights.containsKey(key))
{
website flyweight=new concretewebsite(key);
flyweights.put(key, flyweight);
}
return flyweights.get(key);
}
public int getwebsitecount() {//获得网站分类总数
return flyweights.size();
}
}
含有外部状态的程序
package org.zangyu.Flyweight;
import java.util.HashMap;
public class flyweight30 {
public static void main(String[] args) {
// TODO Auto-generated method stub
websitefactory f= new websitefactory();
website web1 = f.getwebsite("产品展示");
web1.Use(new user("小臧1"));
website web2 = f.getwebsite("产品展示");
web2.Use(new user("小臧2"));
website web3 = f.getwebsite("产品展示");
web3.Use(new user("小臧3"));
website web4 = f.getwebsite("博客");
web4.Use(new user("小臧4"));
website web5 = f.getwebsite("博客");
web5.Use(new user("小臧5"));
website web6 = f.getwebsite("博客");
web6.Use(new user("小臧6"));
System.out.println("网站分类总数"+f.getwebsitecount());
}
}
class user{//外部状态用户类
private String name;
public user(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
abstract class website{//网站抽象类
public abstract void Use(user user);
//参数user是在website外定义的一个类user,在方法use调用时传参
}
class concretewebsite extends website{
private String name;
public concretewebsite(String name) {
this.name=name;
}
@Override
public void Use(user user) {
// TODO Auto-generated method stub
System.out.println("网站分类:"+name+"用户:"+user.getName());
}
}
class websitefactory{
private static HashMap<String,website>flyweights=new HashMap<String,website>();
//获得该网站分类
public website getwebsite(String key)
{
if(!flyweights.containsKey(key))
{
website flyweight=new concretewebsite(key);
flyweights.put(key, flyweight);
}
return flyweights.get(key);
}
public int getwebsitecount() {//获得网站分类总数
return flyweights.size();
}
}
享元模式的特点
避免重复创建对象,节省内存空间。根据内部状态把对象存储在共享池,需要时去共享池取就行。
享元模式使用场景
借用设计模式书中的话就是:如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。