zoukankan      html  css  js  c++  java
  • 设计模式笔记——装饰模式

    装饰模式

    装饰模式(Decorator),动态地给一个对象加入一些额外的职责,就添加功能来说。装饰模式比生成子类更为灵活。

    1.装饰模式的特点

    (1)装饰对象和真实对象有同样的接口。

    这样client对象就能以和真实对象同样的方式和装饰对象交互。

    (2)装饰对象包括一个真实对象的引用(reference)

    (3)装饰对象接受全部来自client的请求。

    它把这些请求转发给真实的对象。

    (4)装饰对象能够在转发这些请求曾经或以后添加一些附加功能。这样就确保了在执行时,不用改动给定对象的结构就能够在外部添加附加的功能。

    在面向对象的设计中,一般是通过继承来实现对给定类的功能扩展。

    2.适用性

    (1)须要扩展一个类的功能。或给一个类加入附加职责。

    (2)须要动态的给一个对象加入功能。这些功能能够再动态的撤销。

    (3)须要添加由一些基本功能的排列组合而产生的很大量的功能。从而使继承关系变的不现实。

    (4)当不能採用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。还有一种情况可能是由于类定义被隐藏,或类定义不能用于生成子类。

     

    全部设计模式总结请參考:http://blog.csdn.net/chr23899/article/details/46999267

    全部设计原则总结请參考:http://blog.csdn.net/chr23899/article/details/46999401

     

    首先来看下详细的效果图

     

     






    从效果图中我们能够看出用户在生成草原时能够用八中选择: 不装饰、太阳、白云、小花、太阳+白云、太阳+小花、白云+小花、全装饰。假设採用创建子类的方式。则须要七个子类来完毕对应的功能,这就会出现’子类爆炸’的现象。假设装饰模式则能够动态的加入装饰而避免此类现象的发生。

    先看下详细的装饰类图效果


     

      


    类的具体设计代码例如以下:

    //定义草原抽象类
        public abstract class GrassLand
        {
            //抽象方法 用于重写
            public abstract void draw(PictureBox pic, Graphics g);
        }
    
        //定义初始子类LandModel
        public class LandModel : GrassLand
        {
            //实现抽象函数
            public override void draw(PictureBox picbox_img, Graphics g)
            {  
                //蓝天
                g.FillRectangle(Brushes.Blue, 0, 0, picbox_img.Width, picbox_img.Height);
                //绿草
                g.FillPie(Brushes.Green, 0, picbox_img.Height / 4 * 3, picbox_img.Width * 2, picbox_img.Height / 2, 180, 270);
            }
        }
    
        //定义装饰者类
        public class Decorator : GrassLand
        {
            //定义草场对象
            private GrassLand land;
    
            //构造函数赋初值
            public Decorator(GrassLand l)
            {
                land = l;
            }
    
            //重写draw方法
            public override void draw(PictureBox pic, Graphics g)
            {
                if (land != null)
                    land.draw(pic, g);
            }
        }
        
        //绘制太阳
        public class DrawSun : Decorator
        {
            public DrawSun(GrassLand land)
                : base(land)
            {
            }
    
            public override void draw(PictureBox pic, Graphics g)
            {
                base.draw(pic, g);
                addsun(pic, g);
            }
    
            //完毕要装饰的内容
            private void addsun(PictureBox picbox_img, Graphics g)
            {
                //太阳
                g.FillEllipse(Brushes.Red, picbox_img.Width / 8, picbox_img.Height / 8, picbox_img.Width / 7, picbox_img.Width / 7);
            }
        }
    
        //绘制白云
        public class DrawCloud : Decorator
        {
            public DrawCloud(GrassLand land)
                : base(land)
            {
            }
    
            public override void draw(PictureBox pic, Graphics g)
            {
                base.draw(pic, g);
                addcloud(pic, g);
            }
    
            //完毕要装饰的内容
            private void addcloud(PictureBox picbox_img, Graphics g)
            {
                //白云
                g.FillEllipse(Brushes.GhostWhite, picbox_img.Width / 8 * 3, picbox_img.Height / 6, picbox_img.Width / 7, picbox_img.Height / 9);
                g.FillEllipse(Brushes.GhostWhite, picbox_img.Width / 8 * 6, picbox_img.Height / 6, picbox_img.Width / 7, picbox_img.Height / 9);
                g.FillEllipse(Brushes.GhostWhite, picbox_img.Width / 16 * 9, picbox_img.Height / 4, picbox_img.Width / 7, picbox_img.Height / 9);
            }
        }
    
        public class DrawFlower : Decorator
        {
            public DrawFlower(GrassLand land)
                : base(land)
            {
            }
    
            public override void draw(PictureBox pic, Graphics g)
            {
                base.draw(pic, g);
                addflower(pic, g);
            }
    
            //完毕要装饰的内容
            private void addflower(PictureBox picbox_img, Graphics g)
            {
                //小花
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 9, picbox_img.Height - 10, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 7, picbox_img.Height - 20, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 5, picbox_img.Height - 30, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 3, picbox_img.Height - 28, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 16 * 15, picbox_img.Height - 45, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 16 * 13, picbox_img.Height - 58, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 16 * 11, picbox_img.Height - 15, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 16 * 9, picbox_img.Height - 27, 10, 8);
                g.FillEllipse(Brushes.Pink, picbox_img.Width / 16 * 7, picbox_img.Height - 39, 10, 8);
            }
        }



    3.在装饰者模式中各个角色有:

    (1)抽象构件(GrassLand)角色: 给出一个抽象接口,以规范准备接受附加责任的对象。

    (2)详细构件(LandModel)角色: 定义一个将要接收附加责任的类。

    (3)装饰(Decorator)角色: 持有一个构件(GrassLand)对象的实例。并定义一个与抽象构件接口一致的接口。

    (4)详细装饰(DrawSun、DrawCloud和DrawFlower)角色: 负责给构件对象 ”贴上“附加的责任。

     

    4.装饰模式的长处:

    (1)Decorator模式与继承关系的目的都是要扩展对象的功能,可是Decorator能够提供比继承很多其它的灵活性。

    (2)通过使用不同的详细装饰类以及这些装饰类的排列组合,设计师能够创造出非常多不同行为的组合。

     

    源程序下载地址:http://download.csdn.net/detail/chr23899/8925611

    原文出处:http://blog.csdn.net/chr23899 转发请说明

      

  • 相关阅读:
    <Error>: CGContextRestoreGState
    Google 常用镜像收集
    NSCharacterSet 详解
    JAVA并发,CyclicBarrier
    JAVA并发,CountDownLatch使用
    JAVA并发,经典死锁案例-哲学家就餐
    Git-常用命令集合
    (转)《JAVA与模式》之模板方法模式
    JAVA并发,同步锁性能测试
    《转》JAVA并发编程:volatile关键字解析
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6781859.html
Copyright © 2011-2022 走看看