zoukankan      html  css  js  c++  java
  • 软件工程 设计模式学习之装饰模式Decorator

    技术交流,DH讲解

    如果我们想在不改变已有类的情况下,然后加上新的功能.
    这个时候我们就可以使用装饰模式了.
    惯例先看下这个设计模式的UML图.
    decorator
    装饰模式关键是方法重载.override.
    说了这么多我们来用代码来说话.


    老规矩,第一个是PHP了.
    class Person{
        var $name='';
        function __construct($a){
            $this->name=$a;
        }
        public function show(){
            echo("this is ".$this->name."!!!\n");
        }
    }
    //穿着的基类
    class Finery extends Person{
        protected $component;
        public function decorator($aPerson){
            $this->component=$aPerson;
        }
        public function show() {
            if(isset($this->component))
                $this->component->show();
        }
    }
    //具体的类.
    Class Tshirt extends Finery{
         public function show() {
             echo("My TShirt@!\n");
             parent::show();
         }
    }
    //具体类2
    class Tie extends Finery{
         public function show(){
            echo("My Tie!!\n");
            parent::show();
         }
    }
    //Test

       $p = new Person("HuangJacky");
       $tshirt = new Tshirt();
       $tie = new Tie();

       $tshirt->decorator($p);
       $tie->decorator($tshirt);
       $tie->show();
    我们看看输出结果吧.
    My Tie!! My TShirt@! this is HuangJacky!!!

    我们可以看见关键的地方:
    parent::show();


    接下来我们还是用Java来

    class Person{
        private String Name;
        public Person(){
            this.Name="HuangJacky";
        }
        public Person(String aName){
            this.Name=aName;
        }
        public void show(){
            System.out.println("my name is " + Name + "!\n");
        }
    }
    class Finery extends Person{
        protected Person cmp=null;
        public void decorator(Person a){
            this.cmp=a;
        }
        public void show(){
            if(cmp!=null)
                cmp.show();
        }
    }
    class TShirt extends Finery{
        public void show(){
            System.out.println("My TShirt!\n");
            super.show();
        }
    }
    class Tie extends Finery{
        public void show(){
            System.out.println("My Tie!\n");
            super.show();
        }
    }
    
    class Person{
        private String Name;
        public Person(){
            this.Name="HuangJacky";
        }
        public Person(String aName){
            this.Name=aName;
        }
        public void show(){
            System.out.println("my name is " + Name + "!\n");
        }
    }
    class Finery extends Person{
        protected Person cmp=null;
        public void decorator(Person a){
            this.cmp=a;
        }
        public void show(){
            if(cmp!=null)
                cmp.show();
        }
    }
    class TShirt extends Finery{
        public void show(){
            System.out.println("My TShirt!\n");
            super.show();
        }
    }
    class Tie extends Finery{
        public void show(){
            System.out.println("My Tie!\n");
            super.show();
        }
    }
    public class Main {
        public static void main(String[] args) {
            Person p = new Person("TheFiend");
            TShirt t = new TShirt();
            Tie T = new Tie();
            t.decorator(p);
            T.decorator(t);
            T.show();
        }
    }

    其实代码都是一样,只是语言不同而已.
    super.show();
    在C#里面我们就需要改成base.show();


    最后进入Delphi Time.
    Type
    TPerson = Class
    Private
    Name: String;
    Public
    Constructor Create( Const AName: String );
    Procedure Show( ); Virtual;
    End;
    TFinery = Class( TPerson )
    Private
    FPerson: TPerson;
    Public
    Procedure Show( ); Override;
    Property Person: TPerson Read FPerson Write FPerson;
    End;
    TTShirt = Class( TFinery )
    Public
    Procedure Show( ); Override;
    End;
    TTie = Class( TFinery )
    Public
    Procedure Show( ); Override;
    End;
    { TPerson }
    Constructor TPerson.Create( Const AName: String );
    Begin
    Self.Name := AName;
    End;
    Procedure TPerson.Show;
    Begin
    Writeln( 'my name is ' + Name );
    End;
    { TFinery }
    Procedure TFinery.Show;
    Begin
    If Assigned( FPerson ) Then
    FPerson.Show;
    End;
    { TTShirt }
    Procedure TTShirt.Show;
    Begin
    Writeln( 'My Shirt' );
    Inherited;
    End;
    { TTie }
    Procedure TTie.Show;
    Begin
    Writeln( 'My Tie!' );
    Inherited;
    End;
    测试:
    Var
    P: TPerson;
    T: TTShirt;
    I: TTie;
    S: String;
    Begin
    P := TPerson.Create( 'HuangJacky' );
    T := TTShirt.Create( '' );
    I := TTie.Create( '' );
    T.Person := P;
    I.Person := T;
    I.Show;
    Readln( S );
    End.
    OK,Delphi也是这样的.
    我们可以看到Delphi里面是一句Inherited;因为调用的是父类的同名同参数的函数 所以函数名可以省略掉.不然就要写成
    Inherited show();了
    总结下,装饰模式适用的情况:
    • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
    • 处理那些可以撤消的职责。
    • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,
    • 为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
    • 另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
    就到这里,我是DH.
  • 相关阅读:
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之多方式虚拟直播
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之点播分享
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器与EasyDSS流媒体解决方案的不同
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器软件实现的多码率视频点播功能说明
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之Windows服务安装
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之Nodejs调用bat或sh脚本
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之Grunt的使用简介
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器启用https服务申请免费证书
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器软件二次开发接口对接说明示列
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器和EasyDSS云平台异同
  • 原文地址:https://www.cnblogs.com/huangjacky/p/1619796.html
Copyright © 2011-2022 走看看