逐步分析Main
方法中的代码执行过程,以及在执行过程中各个方法的调用顺序和输出。
cs
using System;
namespace 装饰模式的实现
{
/// <summary>
/// 房子抽象接口
/// </summary>
public abstract class House
{
public abstract void Renovate();
}
/// <summary>
/// 装饰抽象类
/// </summary>
public abstract class DecorationStrategy : House
{
protected House _house;
protected DecorationStrategy(House house)
{
_house = house ?? throw new ArgumentNullException(nameof(house)); // 参数检查
}
public override void Renovate()
{
_house?.Renovate();
}
}
/// <summary>
/// 具体房子
/// </summary>
public sealed class StarDengHouse : House
{
public override void Renovate()
{
Console.WriteLine("装修StarDeng的房子");
}
}
/// <summary>
/// 安全装饰器
/// </summary>
public sealed class HouseSecurityDecorator : DecorationStrategy
{
public HouseSecurityDecorator(House house) : base(house) { }
public override void Renovate()
{
base.Renovate();
Console.WriteLine("增加安全系统");
}
}
/// <summary>
/// 保温装饰器
/// </summary>
public sealed class KeepWarmDecorator : DecorationStrategy
{
public KeepWarmDecorator(House house) : base(house) { }
public override void Renovate()
{
base.Renovate();
Console.WriteLine("增加保温的功能");
}
}
public class Program
{
static void Main()
{
House myHouse = new StarDengHouse();
// 创建装饰器
House securityHouse = new HouseSecurityDecorator(myHouse);
House securityAndWarmHouse = new KeepWarmDecorator(securityHouse);
// 装饰房子
securityAndWarmHouse.Renovate();
Console.ReadLine();
}
}
}
代码执行逻辑分析
-
创建具体房子实例:
House myHouse = new StarDengHouse();
- 这里创建了一个
StarDengHouse
的实例,myHouse
代表一个具体的房子。
- 这里创建了一个
-
创建安全装饰器实例:
House securityHouse = new HouseSecurityDecorator(myHouse);
- 这行代码创建了一个
HouseSecurityDecorator
实例,传入了myHouse
。 - 在
HouseSecurityDecorator
的构造函数中,会调用基类DecorationStrategy
的构造函数,初始化_house
字段为myHouse
。
- 这行代码创建了一个
-
创建保温装饰器实例:
House securityAndWarmHouse = new KeepWarmDecorator(securityHouse);
- 这行代码创建了一个
KeepWarmDecorator
实例,传入了securityHouse
。 - 在
KeepWarmDecorator
的构造函数中,会调用基类DecorationStrategy
的构造函数,初始化_house
字段为securityHouse
。
- 这行代码创建了一个
-
装饰房子:
securityAndWarmHouse.Decorate();
- 这里调用
securityAndWarmHouse.Decorate()
,我们将跟踪这个方法的调用过程。
- 这里调用
调用过程详细分析
-
调用
KeepWarmDecorator.Decorate()
:- 该方法首先调用
base.Decorate()
,即DecorationStrategy.Decorate()
。
- 该方法首先调用
-
调用
DecorationStrategy.Decorate()
:- 在此方法中,调用
_house.Decorate()
,这里_house
是securityHouse
,即HouseSecurityDecorator
。
- 在此方法中,调用
-
调用
HouseSecurityDecorator.Decorate()
:- 在
HouseSecurityDecorator
的Decorate()
方法中,首先调用base.Decorate()
,即DecorationStrategy.Decorate()
。
- 在
-
再次调用
DecorationStrategy.Decorate()
:- 在这个方法中,再次调用
_house.Decorate()
,这次_house
是myHouse
,即StarDengHouse
。
- 在这个方法中,再次调用
-
调用
StarDengHouse.Decorate()
:- 这个方法输出
"装修StarDeng的房子"
。
- 这个方法输出
输出顺序
随着调用的返回,输出的顺序将是:
-
StarDengHouse.Decorate()
输出:装修StarDeng的房子
-
HouseSecurityDecorator.Decorate()
输出:增加安全系统
-
KeepWarmDecorator.Decorate()
输出:增加保温的功能
最终输出结果
因此,整个程序执行后,控制台的输出将是:
装修StarDeng的房子
增加安全系统
增加保温的功能
总结
通过上述分析,我们清楚地看到,装饰器模式通过递归调用的方式,依次执行各个装饰器的逻辑,最终实现了对原始功能的增强。每个装饰器都在原有功能的基础上添加了自己的特性,使得整个系统具备了灵活性和可扩展性。