黑马程序员技术交流社区

标题: 享元设计模式 [打印本页]

作者: 唐长智    时间: 2013-1-29 22:04
标题: 享元设计模式
本帖最后由 张向辉 于 2013-1-31 22:07 编辑

Flyweight享元设计模式:
        有很多小的对象,很多拥有相同的地方。可以将他们变成一个对象。不同的地方通过方法的参数,将这些不同的东西传进去。
看到张孝祥老师的视频讲了享元设计模式,定义也清楚了,但是还是不太理解在实际的操作中是怎么应用的,有同学写过这个设计模式的代码么?分享一下啊。


作者: 杨玲    时间: 2013-1-29 22:56
很少用到枚举.没什么概念!呵呵,
作者: 梁永奇    时间: 2013-1-30 10:45
既然定义你已经清楚了,那我简单说一下我的理解。
张老师视频中讲到,比如你使用word写东西,对于字母a,b,c,如果每次用到a,都要创建一个对象,那么一篇文章下来,由于a所创建的对象就会非常多了,所以面对这种问题,能不能考虑只创建一个a对象呢,就是说所有的a都是一个对象,只是在不同地方的使用,对于a所在的不同位置,只要加上坐标来确定就行。
因为咱们这个阶段暂时用不上享元模式,例子的话,你可以再看看张老师用Integer创建对象的那个例子
作者: Rancho_Gump    时间: 2013-1-30 11:07
网上看到的例子,很给力
  1. import java.util.ArrayList;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;


  5. abstract class Order {
  6. //执行卖出动作
  7. public abstract void sell();
  8. //获取咖啡口味
  9. public abstract String getFlavor();
  10. }

  11. class FlavorOrder extends Order{
  12. private String flavor;

  13. public FlavorOrder(String flavor){
  14. this.flavor = flavor;
  15. }

  16. public String getFlavor(){
  17. return this.flavor;
  18. }

  19. public void sell(){
  20. System.out.println("卖出一杯 [" + flavor + "]。" );
  21. }
  22. }


  23. class FlavorFactory {
  24. //订单池
  25. private Map<String,Order> flavorPool = new HashMap<String,Order>(20);

  26. //静态工厂,负责生成订单对象
  27. private static FlavorFactory flavorFactory = new FlavorFactory();

  28. private FlavorFactory() {}

  29. public static FlavorFactory getInstance() {
  30. return flavorFactory;
  31. }

  32. //获得订单
  33. public Order getOrder(String flavor) {
  34. Order order = null;
  35. if(flavorPool.containsKey(flavor)){
  36. order = flavorPool.get(flavor);
  37. }else{
  38. //获得新口味订单
  39. order = new FlavorOrder(flavor);
  40. //放入对象池
  41. flavorPool.put(flavor, order);
  42. }
  43. return order;
  44. }

  45. //获得已经卖出的咖啡全部口味数量
  46. public int getTotalFlavorsMade() {
  47. return flavorPool.size();
  48. }
  49. }

  50. public class xiangyunmoshi {
  51. //客户下的订单
  52. private static List<Order> orders = new ArrayList<Order>(100);

  53. //订单对象生成工厂
  54. private static FlavorFactory flavorFactory;

  55. //增加订单
  56. private static void takeOrders(String flavor) {
  57. orders.add(flavorFactory.getOrder(flavor));
  58. }

  59. public static void main(String[] args) {
  60. //订单生成工厂
  61. flavorFactory = FlavorFactory.getInstance();

  62. //增加订单
  63. takeOrders("摩卡");
  64. takeOrders("卡布奇诺");
  65. takeOrders("香草星冰乐");
  66. takeOrders("香草星冰乐");
  67. takeOrders("拿铁");
  68. takeOrders("卡布奇诺");
  69. takeOrders("拿铁");
  70. takeOrders("卡布奇诺");
  71. takeOrders("摩卡");
  72. takeOrders("香草星冰乐");
  73. takeOrders("卡布奇诺");
  74. takeOrders("摩卡");
  75. takeOrders("香草星冰乐");
  76. takeOrders("拿铁");
  77. takeOrders("拿铁");

  78. //卖咖啡
  79. for(Order order : orders){
  80. order.sell();
  81. }

  82. //打印生成的订单java对象数量
  83. System.out.println("n客户一共买了 " + orders.size() + " 杯咖啡! ");

  84. //打印生成的订单java对象数量
  85. System.out.println("n共生成了 " + flavorFactory.getTotalFlavorsMade() + " 个 FlavorOrder java对象! ");
  86. }
  87. }
复制代码

作者: 黑马王振宇    时间: 2013-1-30 11:11
定义你都理解了那就好办了。
我举个例子:开发游戏的时候,表示数字的时候都很好看吧,比方说很多字体补丁包啊,数字多彩补丁包啊等等,
一个人物比如说有上万的血量(五位数),那你不能把所有的人物可能拥有的血量都排列组合出来搞几万张好看的数字图片吧,
这样也不效率,也不实际,那么就用享元模式吧,把10个阿拉伯数字拆开成0-9十张图片存起来,用这十张图组合来表示这个五位数,
比如,血量需要运算,假设血量是int型26584,程序(或方法)会把这个int型的数据转换成单个的"2","6","5","8","4",然后去图片库分别找这几个数对应的图片
然后在屏幕上显示出来,比方说一个图片大小是20*20,那么现实的时候就是2对应的图片显示在(X,Y)位置,6对应的图片显示在(X+20,Y)的位置,这样依次显示5张图
给我们的感觉就是连续的完整的图片来表示血量就可以了。当被攻击血少的时候也是通过运算之后,再把int型血量数据按照上边的方法表示出来就行了,
这就解决了用十张图片解决表示上万种可能血量的方法了。不知道说的和你问的是一个问题不。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2