|   登录   |   注册   |   设为首页   |   加入收藏   

用户登录

close

用户名:

密码:

新用户注册

close

用户名:

密码:

密码确认:

电子邮箱:

关注内容:

个人主页:

帮助

close

龙宇网成立于2008年3月,网站进入整体运作于2010年10月1日。

在这里,我们把它做成了一个真正意义上的网站,完全以个人的信息为内容,以网友的需要为主导,全力搜罗各种信息,建立完善的网站功能,使网友在这里可以第一时间找到所需要的信息。

现在,经过三年的努力,网站的资料已经相当丰富,而网站得到了大家的喜爱和认可。

但,我们还是会继续努力下去,让网间的这份快乐继续持续下去,让这份闲暇时的日子,与快乐一并同行。

寻觅快乐,网住快乐,关注网络,是龙宇网的宣言与承诺。

设计模式之装饰模式

分类: 系统架构 发布时间: 2016-12-01 13:46:35 浏览次数: 2119
内容提要: JAVA23种设计模式之一,英文叫Decorator Pattern,又叫装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

下班回家无聊在加上本命年有些不太顺利,决定看男人帮打发下班的无聊时间,点击第十八集,开场白:

        我们生活在这个 一秒钟一个变化的世界里 有时候友情比爱情更为可靠 朋友可以在你最艰苦的时候 默默守候 在你一切平安的时候 云淡风轻的离开 爱人有事相反 男人和女人的友情又不一样 男人如此粗暴而简单 女人的友情温婉而复杂 当男女的友情 遇到了男女的爱情 就会迅速变成两个阵营!
        尾语:我们都需要爱情 就像我们都需要友情一样 我们在这个世界上不断地找寻 因为我们缺一不可

       1.场景模拟

        这样让想起了老李,我跟老李是很要好的哥们,当然他不像我还是光棍,所以他不光有友情还有爱情了,不过,就在最近几天他们吵架啦,什么原因?就不多说啦,总之身为男人的老李还是决定主动认错挽回女方了,但是挽回女方不像约会打扮的靓丽是一方面,重要的是道歉的诚意呀,例如:一封道歉信,一束玫瑰花,带上第一次女方送的围巾来表示诚意等等。我想这样的打扮加上诚恳的态度,一定会成功归来啦!       

        那么我们就用代码来实现吧: 

复制代码
  public class MrLi
    {
        private const string name = "limou";

        /// <summary>
        /// 道歉信
        
/// </summary>
        public void Letters()
        {
            Console.Write("道歉信 ");
        }

        /// <summary>
        /// 玫瑰花
        
/// </summary>
        public void Rose()
        {
            Console.Write("玫瑰花 ");
        }

        /// <summary>
        /// 围巾
        
/// </summary>
        public void Scarf()
        {
            Console.Write("女友送的围巾 ");
        }

        /// <summary>
        /// 带上挽回女友的东西
        
/// </summary>
        public void Operation()
        {
            Console.WriteLine("带上:");
            this.Letters();
            this.Rose();
            this.Scarf();
        }
    }
  static void Main(string[] args)
  {
        MrLi li = new MrLi();
        //带上东西
        li.Operation();
        Console.WriteLine();
  }
复制代码

 

        运行结果如下:

        

        刚完成以上代码,就接到老李的电话说成功啦,用这招还真管用啊,我说那我们明天晚上吃饭庆祝一下吧?老李说:“不行啦,我们刚和好,明天晚上我只属于我女朋友啦。我要跟她一起吃饭噢!”,我晕,重色轻友啊!

        那他明天跟女友约会肯定不会再是这一套了,肯定不管用了,如果他明天继续带上玫瑰花,带上太阳镜和围巾呢?这个时候我们刚才实现的类好像就不能满足了,怎么办呢?最烂的办法就是在MrLi类中加入一个带上太阳镜的方法,为什么是最烂的方法呢?因为他违背了面向对象原则中的开放-封闭原则。那么什么是开放封闭原则呢?

        开放封闭原则:类可扩展,但不可修改。

        那么如何能支持MrLi的装扮可以自定义随意变换呢?不要着急先看看装饰模式吧!

        2.装饰模式

         装饰模式:装饰模式是动态的给对象增加责任,对扩展来功能说,装饰模式提供了比继承更灵活的方案

         装饰模式类图如下:

        Component类:用来抽象装饰对象与被装饰对象的共同的装饰行为。

        ConcreteComponent类:是一个被装饰的主对象。

        Decorator类:是一个用来装饰的抽象类,包含了Component类的实例与实现了装饰与被装饰对象的共同行为,包含Component类实例表示将来具体的装饰类都有一个明确的被装饰对象

        ConcreteDecratorAConcreteDecratorB类:是具体装饰类实例,该对象实现了抽象的Decorator类,包含一个被装饰对象用来装饰此对象。

        装饰模式代码如下:

复制代码
  /// <summary>
    /// 装饰行为的抽象
    
/// </summary>
    public abstract class Component
    {
        //操作
        public abstract void Operation();
    }

    /// <summary>
    /// 被装饰的对象
    
/// </summary>
    public class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.WriteLine("具体对象的操作");
        }
    }

    /// <summary>
    /// 抽象的装饰类
    
/// </summary>
    public abstract class Decorator : Component
    {
        protected Component component;

        public void SetComponent(Component component)
        {
            this.component = component;
        }

        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }

    /// <summary>
    /// 具体的装饰类
    
/// </summary>
    public class ConcreteDecoratorA : Decorator
    {
        private void AddedBehaviorA()
        {
            Console.WriteLine("装饰A");
        }

        public override void Operation()
        {
            base.Operation();
            AddedBehaviorA();
        }
    }

    public class ConcreteDecoratorB : Decorator
    {
        private void AddedBehaviorB()
        {
            Console.WriteLine("装饰B");
        }

        public override void Operation()
        {
            base.Operation();
            AddedBehaviorB();
        }
    }
复制代码

        主函数调用如下:

复制代码
        static void Main(string[] args)
        {
            //定义被装饰对象 主装饰对象
            ConcreteComponent cc = new ConcreteComponent();
            //定义具体装饰对象A 主对象上的装饰
            ConcreteDecoratorA cda = new ConcreteDecoratorA();
            //定义具体装饰对象A 主对象上的装饰
            ConcreteDecoratorB cdb = new ConcreteDecoratorB();

            //装饰对象A 装扮主对象cc
            cda.SetComponent(cc);
            //装饰对象B 装扮装饰对象A
            cdb.SetComponent(cda);
            //开始装扮
            cdb.Operation();

            //第二种装扮
            
//装饰对象B 装扮主对象cc
            cdb.SetComponent(cc);
            //装饰对象A 装扮装饰对象B
            cda.SetComponent(cdb);
            //开始装扮
            cda.Operation();
      }
复制代码

        可以看到,有了装饰模式,我们可以轻易的增加装饰对象,并且灵活的组织装饰对象装扮的顺序,那如果我们用装饰模式实现我们第一部分的场景应该如何呢?

        3.装饰模式的灵活运用

         那我们设计的类图如下:

         代码实现如下:

复制代码
   /// <summary>
    /// 打扮的抽象类
    
/// </summary>
    public abstract class DressUp
    {
        //开始打扮
        public abstract void ToDressUp();
    }

    /// <summary>
    /// 被装饰的对象,老李,围巾等饰品都是装饰在他身上
    
/// </summary>
    public class MrLi : DressUp
    {
        private const string name = "limou";

        /// <summary>
        /// 开始打扮
        
/// </summary>
        public override void ToDressUp()
        {
            Console.WriteLine("{0}开始打扮如下饰品:",name);
        }
    }

    /// <summary>
    /// 装饰品抽象类
    
/// </summary>
    public abstract class Decorator:DressUp
    {
        //实现一个被装饰对象用来记录装饰谁
        protected DressUp component = null;

        /// <summary>
        /// 设置被打扮对象
        
/// </summary>
        /// <param name="com"></param>
        public void SetDressUp(DressUp com)
        {
            this.component = com;
        }

        /// <summary>
        /// 默认的装扮实现
        
/// </summary>
        public override void ToDressUp()
        {
            if (component != null)
            {
                component.ToDressUp();
            }
        }
    }

    /// <summary>
    /// 道歉信装饰类
    
/// </summary>
    public class Letters : Decorator
    {
        /// <summary>
        /// 开始打扮
        
/// </summary>
        public override void ToDressUp()
        {
            base.ToDressUp();
            Console.Write("道歉信 ");
        }
    }

    /// <summary>
    /// 玫瑰花装饰类
    
/// </summary>
    public class Rose : Decorator
    {
        /// <summary>
        /// 开始打扮
        
/// </summary>
        public override void ToDressUp()
        {
            base.ToDressUp();
            Console.Write("玫瑰花 ");
        }
    }

    /// <summary>
    /// 围巾装饰类
    
/// </summary>
    public class Scarf : Decorator
    {
        /// <summary>
        /// 开始打扮
        
/// </summary>
        public override void ToDressUp()
        {
            base.ToDressUp();
            Console.Write("女友送的围巾 ");
        }
    }

    /// <summary>
    /// 太阳镜装饰类,可以添加需要的装饰类
    
/// </summary>
    public class Sunglasses :Decorator
    {
        /// <summary>
        /// 开始打扮
        
/// </summary>
        public override void ToDressUp()
        {
            base.ToDressUp();
            Console.Write("太阳眼镜 ");
        }
    }
复制代码

    主函数调用如下:

复制代码
        static void Main(string[] args)
        {
            MrLi li = new MrLi();

            //第一天道歉的打扮
            Console.WriteLine("第一天道歉的打扮:");
            //道歉信
            Letters letters = new Letters();
            //玫瑰花
            Rose rose = new Rose();
            //女友送的围巾
            Scarf scarf = new Scarf();

            //打扮道歉信
            letters.SetDressUp(li);
            //打扮玫瑰
            rose.SetDressUp(letters);
            //打扮围巾
            scarf.SetDressUp(rose);
            //开始打扮
            scarf.ToDressUp();
            Console.WriteLine();
            Console.WriteLine("--------------------------------------");
            //第二天约会的打扮
            Console.WriteLine("第二天约会的打扮");
            //道歉信
            Letters let = new Letters();
            //太阳镜
            Sunglasses sunglasses = new Sunglasses();
            //女友送的围巾
            Scarf sca = new Scarf();

            //打扮道歉信
            let.SetDressUp(li);
            //打扮玫瑰
            sunglasses.SetDressUp(let);
            //打扮围巾
            sca.SetDressUp(sunglasses);
            //开始打扮
            sca.ToDressUp();
            Console.WriteLine();
      }
复制代码

     运行结果如下:

    

    这样利用装饰模式就可以有效的解决将来对新装饰品的扩展而无需去修改原先的类,完全的满足了开放封闭原则。

0
0

分类: 系统架构   |   评论: 0   |   引用: 0   |   浏览次数: 2119