享元模式
运用共享技术有效的支持大量细粒度的对象。
但是这样算是基本实现了享元模式的共享对象的目的,不管建几个网站,只要购物网站都是一样的,只要是游戏网站也是完全相同的,但是这样也成为了一个问题,你给用户建造的网站不是一模一样的,他们的数据是不可能一样的,所以至少他们都应该有自己的账号。
内部状态和外部状态
在享元对象内部并且不会随环境改变而改变的共享部分,可以成为享元对象的内部状态,而随环境改变而改变的,不可以共享的状态就是外部状态。如果能发现这些实例除了几个参数外基本上都是相同的,如果能把这些参数移动到类实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅度的减少单个实例的数目。内部状态存储与ConcreteFlyweight对象中,外部对象应该考虑有客户端存储或者计算。
website(抽象类):
public abstract class WebSite {
protected String name;
public WebSite(String name){
this.name = name;
}
//使用
public abstract void use(User user);
}
具体的网站:
public class ConcreteWeb extends WebSite {
public ConcreteWeb(String name){
super(name);
}
@Override
public void use(User user) {
System.out.println("网站分类:"+this.name+"-----使用者:"+user.getName());
}
}
网站工厂:
public class WebFactory {
private HashMap<String,WebSite> webSites = new HashMap<>();
public WebSite getWebSite(String key){
//如果没有该类型的网站,创建网站
if(!webSites.containsKey(key)){
webSites.put(key,new ConcreteWeb(key));
}
//取出网站
return webSites.get(key);
}
public int webCount(){
return webSites.size();
}
}
外部状态(外部状态):
//外部对象
public class User {
private String name;
public User(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
客户端
public class Client {
public static void main(String[] args) {
WebFactory webFactory = new WebFactory();
//创建网站
WebSite web = webFactory.getWebSite("购物网站");
//使用者
User user = new User("小张");
web.use(user);
//创建网站
WebSite web1 = webFactory.getWebSite("游戏网站");
//使用者
User user1 = new User("小轩");
web1.use(user1);
//创建网站
WebSite web2 = webFactory.getWebSite("购物网站");
//使用者
User user2 = new User("小明");
web2.use(user2);
System.out.println("网站分类总数"+webFactory.webCount());
}
}
网站分类:购物网站-----使用者:小张
网站分类:游戏网站-----使用者:小轩
网站分类:购物网站-----使用者:小明
网站分类总数2
应用
如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用,还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时就可以考虑使用享元对象。