C# 设计模式-装饰器模式

装饰器模式,顾名思义就是对一个主体进行修饰。

原理就是用一个新的类去包含一个旧的类,在新的类中先调用旧的类的方法,再调用新的类中新添加的方法。这样就实现了链式调用。然后可以不断的添加新的修饰类去修饰。

为了能使新的类(装饰类)能够包含旧的类(主体类或者已经经过修饰的修饰类),就需要统一基类,所以不论是主体类还是修饰类都需要继承同一个基类。

 

用代码来举例:

1.定义2个主体类,Man和Women,都继承与Body这一个基类。Body中的Print方法是最关键的,整个链式方法的调用全是通过这个Print方法来实现的。

    public abstract class Body
    {
        public abstract void Print();
    }

    public class Man : Body
    {
        public override void Print()
        {
            Console.WriteLine("男人");
        }
    }

    public class Woman : Body
    {
        public override void Print()
        {
            Console.WriteLine("女人");
        }
    }

2.定义装饰抽象类

    public abstract class Decorator : Body
    {
        public abstract override void Print();
    }

这个抽象类的作用是可以简化很多代码,可以将很多不需要装饰类修改的方法可以在这个抽象类中完成,而不需要再每个装饰类都写一样的方法

3.定义装饰类

    public class Clothes : Decorator
    {
        private readonly Body _body;

        public Clothes(Body body)
        {
            _body = body;
        }

        public override void Print()
        {
            _body.Print();
            Console.WriteLine("穿上衣服");
        }
    }

    public class Shoes : Decorator
    {
        private readonly Body _body;

        public Shoes(Body body)
        {
            _body = body;
        }

        public override void Print()
        {
            _body.Print();
            Console.WriteLine("穿上鞋子");
        }
    }

    public class Pants : Decorator
    {
        private readonly Body _body;

        public Pants(Body body)
        {
            _body = body;
        }

        public override void Print()
        {
            _body.Print();
            Console.WriteLine("穿上裤子");
        }
    }

可以看到,每一个装饰类中的Print方法都是先调用body的Print方法,然后再调用自己的方法。就基本实现了链式调用。

调用

    class Program
    {
        static void Main(string[] args)
        {
            Body man = new Man();
            man = new Shoes(man);
            man = new Pants(man);
            man = new Clothes(man);
            man = new Clothes(man);
            man = new Clothes(man);
            man.Print();
            Console.ReadLine();
        }
    }

结果


还可以采用另外一种方式来定义装饰器抽象类和装饰类。

2.1装饰抽象类

    public abstract class Decorator : Body
    {
        private readonly Body _body;

        protected Decorator(Body body)
        {
            _body = body;
        }

        public override void Print()
        {
            _body.Print();
        }
    }

3.1装饰类

public class Clothes : Decorator
    {
        public Clothes(Body body):base(body)
        {
        }

        public override void Print()
        {
            base.Print();
            Console.WriteLine("穿上衣服");
        }
    }

    public class Shoes : Decorator
    {
        public Shoes(Body body) : base(body)
        {
        }

        public override void Print()
        {
            base.Print();
            Console.WriteLine("穿上鞋子");
        }
    }

    public class Pants : Decorator
    {
        public Pants(Body body) : base(body)
        {
        }

        public override void Print()
        {
            base.Print();
            Console.WriteLine("穿上裤子");
        }
    }

个人比较倾向第一种模式

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值