首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

设计模式有关问题:关于拥有重复资源的对象的设计

2012-02-27 
设计模式问题:关于拥有重复资源的对象的设计如图所示,我需要在一块画板上画若干的元素,这些元素可以是图片

设计模式问题:关于拥有重复资源的对象的设计
如图所示,我需要在一块画板上画若干的元素,这些元素可以是图片,图形或者文字等,每个对象都有自己的x,y坐标以及width,height等,并且每个对象都实现了自己的Draw方法,所以我要画出这么一张图的话,只需要遍历一个对象的集合,逐个调用对象的Draw方法即可。


现在问题也是如图所示,我要在这个画板上绘制许多相同的图,只不过位置不同(或者别的属性有所差别),但它们都是同一个位图文件(如“avatar.jpg”)来的,所以我要生成上图的显示效果,就要new四个对象,每个对象各自去加载avatar.jpg,相当于生成了四个Image,造成了浪费,其实比较节省的方案是只生成一个Image,在不同的地方绘制四次。

大家一起讨论讨论如何设计。在开始前请考虑下面这个因素:

avatar.jpg可能发生改变,我创建了一个监视线程去监视它,如果它发生了改变,就会产生一个Reload的动作,Reload之后,我希望依旧只存在一个Image对象。

模式尽量要简单易懂点,谢谢。


[解决办法]
有点像原型模式
[解决办法]
或都是享元,不过原型更像。
[解决办法]
用装饰模式:把基本图片作为基类,其他属性如x,y坐标以及width,height等都放到继承的装饰类里面来,这样就一个图片了。
[解决办法]
什么狗屁设计模式,纯扯淡

这个设计很简单
多出一层来就行了

你现在只有一类Object,他既负责存储资源,又负责绘制

其实,需要两类对象
一类是用来描述资源的,可以是图片文字
另一类负责绘制,需要指定一个资源,并且规定位置

这个跟即时战略游戏太像了
就是同种单位,你制造了多个实体,多个实体共享一个外观模型,却具有不同的位置和状态
[解决办法]
方法:

C# code
        private Image FillImage(Image img1, Image img2, ImagePosition[] positions)    //以BMP为例        {            MemoryStream ms1 = new MemoryStream();                                    //声明2个图片的流,类似指针            MemoryStream ms2 = new MemoryStream();            img1.Save(ms1, System.Drawing.Imaging.ImageFormat.Bmp);                    //把图片以内存BMP加载到流中            img2.Save(ms2, System.Drawing.Imaging.ImageFormat.Bmp);            int img1rowsize = img1.Size.Width * 3;                                    //计算行偏移 (* 3是RGB像素占位3个 如果是其他的格式需要改)             int img2rowsize = img2.Size.Width * 3;            int img1offsetHeader = 35;                                                //BMP头的偏移量 好像是35            int img2offsetHeader = 35;            byte[] buffer = new byte[img2rowsize];                                    //创建缓冲            foreach (ImagePosition aa in positions)                                    //遍历所有位置            {                int x = aa.X;                                                        //获取坐标                int y = aa.Y;                                if(x > img1.Size.Width || y > img1.Size.Width) continue;            //溢出判断                int xOffset = x * 3;                                                //计算行偏移量                int buffercount = img2rowsize;                if (xOffset > img1rowsize)                                            //计算x溢出                {                    buffercount -= xOffset - img1rowsize;                            //丢弃溢出                    if (buffercount < 0)                                            //防止0读取                    {                        buffercount = 0;                    }                }                                //穷举img2中的每一行                for (int i = 0, l = img2.Size.Height; i < l; i++)                {                    if (y + i > img1.Size.Height) break;                            //y溢出判断                    //从img2中读取1行                    int count = ms2.Read(buffer, img2offsetHeader + i * img2rowsize, buffercount);                    //写入到img1中指定位置                    int rowOffset = img1offsetHeader + y * img1rowsize;                //计算列偏移量                    ms1.Write(buffer, rowOffset + xOffset, count);                }            }            Bitmap img = new Bitmap(ms1);            ms1.Dispose();            ms2.Dispose();            return img;        }
[解决办法]
“所以我要生成上图的显示效果,就要new四个对象,每个对象各自去加载avatar.jpg,相当于生成了四个Image,造成了浪费,其实比较节省的方案是只生成一个Image,在不同的地方绘制四次。”

——这个问题其实很简单,关键是理解清楚“引用”和“对象”。Image对象可以只有一个,new出来的这4个对象各保持一个指向此Image对象的引用就可以了。图片更新了以后,可以调用Image对象的Reload方法重新加载图像,再调用那些new出来的四个对象的Re-paint方法就好了。



热点排行