首页 > 代码库 > 大话设计模式_享元模式(Java代码)

大话设计模式_享元模式(Java代码)

享元模式:运用共享技术有效的支持大量细粒度的对象。

简单描述:1个享元工厂,提供各种类型的享元。如果这些享元存在于工厂对象中,则直接提出给客户端,如果没有,则新建享元并存储起来,同时提供给客户端。享元的外部状态可以由客户端存储并在调用相关需要外部状态的操作时由客户端传入

大话设计模式中的截图:

代码例子:

User类:

 1 package com.longsheng.flyweight;
 2 
 3 //外部状态
 4 public class User {
 5 
 6     private String name;
 7 
 8     public String getName() {
 9         return name;
10     }
11     
12     public User(String name) {
13         this.name = name;
14     }
15     
16 }

AbstractFlyweight类:

1 package com.longsheng.flyweight;
2 
3 public abstract class AbstractFlyweight {
4 
5     public abstract void method(User mUser); 
6     
7 }

ConcreteFlyweight类:

 1 package com.longsheng.flyweight;
 2 
 3 public class ConcreteFlyweight extends AbstractFlyweight{
 4 
 5     private String name;
 6     
 7     public ConcreteFlyweight(String name) {
 8         this.name = name;
 9     }
10     
11     @Override
12     public void method(User mUser) {
13         System.out.println("享元的名字:" + name + "-外部状态:" + mUser.getName());
14     }
15     
16 }

UnsharedConcreteFlyweight类:

 1 package com.longsheng.flyweight;
 2 
 3 public class UnsharedConcreteFlyweight extends AbstractFlyweight{
 4 
 5     private String name;
 6     
 7     public UnsharedConcreteFlyweight(String name) {
 8         this.name = name;
 9     }
10     
11     @Override
12     public void method(User mUser) {
13         System.out.println("不共享的对象,名字:" + name + "-外部状态:" + mUser.getName());
14     }
15     
16 }

FlyweightFactory类:

 1 package com.longsheng.flyweight;
 2 
 3 import java.util.HashMap;
 4 
 5 public class FlyweightFactory {
 6 
 7     private HashMap<String, AbstractFlyweight> mHashMap = new HashMap<String, AbstractFlyweight>();
 8     
 9     public AbstractFlyweight getFlyweight( String key ) {
10         if( !mHashMap.containsKey(key) ) {
11             mHashMap.put(key, new ConcreteFlyweight(key));
12         }
13         return mHashMap.get(key);
14     }
15     
16     public AbstractFlyweight getUnsharedFlyweight(String key) {
17         return new UnsharedConcreteFlyweight(key);
18     }
19     
20     public int getFlyweightCount() {
21         return mHashMap.size();
22     }
23     
24 }

客户端:

 1 package com.longsheng.flyweight;
 2 
 3 public class Client {
 4     
 5     public static void main(String args[]) {
 6         FlyweightFactory mFactory = new FlyweightFactory();
 7         AbstractFlyweight mFlyweight1 = mFactory.getFlyweight("企业网站");
 8         mFlyweight1.method(new User("小A"));
 9         AbstractFlyweight mFlyweight2 = mFactory.getFlyweight("企业网站");
10         mFlyweight2.method(new User("小B"));
11         AbstractFlyweight mFlyweight3 = mFactory.getFlyweight("企业网站");
12         mFlyweight3.method(new User("小C"));
13         AbstractFlyweight mFlyweightA = mFactory.getFlyweight("博客");
14         mFlyweightA.method(new User("大A"));
15         AbstractFlyweight mFlyweightB = mFactory.getFlyweight("博客");
16         mFlyweightB.method(new User("大B"));
17         AbstractFlyweight mFlyweightC = mFactory.getFlyweight("博客");
18         mFlyweightC.method(new User("大C"));
19         
20         System.out.println("享元实例个数为:" + mFactory.getFlyweightCount());
21         
22         AbstractFlyweight mUnsharedFlyweight = mFactory.getUnsharedFlyweight("我的博客");
23         mUnsharedFlyweight.method(new User("菜鸟"));
24     }
25     
26     
27 }

运行结果:

1 享元的名字:企业网站-外部状态:小A
2 享元的名字:企业网站-外部状态:小B
3 享元的名字:企业网站-外部状态:小C
4 享元的名字:博客-外部状态:大A
5 享元的名字:博客-外部状态:大B
6 享元的名字:博客-外部状态:大C
7 享元实例个数为:2
8 不共享的对象,名字:我的博客-外部状态:菜鸟

享元模式可以避免大量非常相类似的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本都相同,有时就能够大幅度的减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅度的减少单个实例的数目。即享元模式Flyweight执行时既有内部状态也有外部状态,内部状态直接存储在享元对象中,外部状态则考虑由客户端存储,并在执行享元对象相应操作时由客户端传入。

如果一个应用程序使用了大量的对象,造成很大的存储开销,则此时应该考虑使用享元模式。另外,存在大量的对象,而这些对象的大部分状态可以外部化,删除这些状态后,大量的对象可以用少量对象取代,则此时应该考虑使用享元模式。

另外,使用享元模式需要额外存储一个记录已有享元的列表,这本身需要耗费资源。而且把大量状态外部化,也使程序的逻辑复杂化。所以只有足够多的实例可供共享时,才值得用享元模式。