第五讲 装饰器模式和代理模式
==========================================OOP和AOP==========================================
预习:AOP概念,新的业务变化或者需求添加,不能影响老的核心代码(功能动态添加)
A B C A前面添加一个验证,然后在A的后面增加一个日志跟踪。
oop:是我们程序设计的指导思想,大的方面,而且设计模式是"格式化"的,在程序设计之初就可以想到的,
aop:是我们opp基础上面的补充,我们按照设计模式设计项目,有些东西可能是没有想到,或者是想到了,但是当时没有实现,我们希望以后在更改,"动态完成"
==========================================装饰器模式==========================================
【1】概念:动态的给对象增加一些额外的职责,而不用破坏原有对象的封装。
或者说,装饰器设计模式是为已有的功能动态的增加更多功能的一种方式。这种方式的特点是要把“装饰的功能”放到
单独的类中,并且让这个类包装它所要装饰的对象。
【2】举例:我们买一个手机,后期加装一个外壳
【3】优点:吧核心代码分离出去,后期动态添加其他方法,可以是接口更灵活,后期扩展更方便
/// 1:装饰器也要实现我们的核心接口
/// 2:装饰器要用类的"聚合关系" 再把接口聚合到装饰器里面
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
//常规的接口编程方法
Console.WriteLine("---------------常规方法调用--------------------------");
IOrderInf myorder = new OrderImpl();
myorder.SubmitOrder();
//现在我们的需求发生了变化,我们需要再提交订单前添加校验,提交订单后添加日志记录,,但是不能修改原来的代码,利用面向对象怎么做 ???
//我们可以使用装饰器来处理,吧核心代码装饰起来
Console.WriteLine("-----------------------------装饰器方式实现--------------------------------");
IOrderInf myorder2 = new DecoratorOrder(new OrderImpl());
myorder2.SubmitOrder()
Console.Read();
}
}
}
namespace ConsoleApplication6.zzl
{
/// <summary>
/// 这是我们的装饰器,
/// 1:装饰器也要实现我们的核心接口
/// 2:装饰器要用类的"聚合关系" 再把接口聚合到装饰器里面
/// </summary>
public class DecoratorOrder:IOrderInf
{
private IOrderInf myorder;
#region 核心接口代码
public DecoratorOrder(IOrderInf order)
{
this.myorder = order;
}
public void GetOrderLIst()
{
}
public void SubmitOrder()
{
//安装业务变化在订单前校验
CheckOrder();
this.myorder.SubmitOrder();
//根据业务变化在提交订单后添加日志
WriteLOg();
}
#endregion
#region 我们业务变化需要修改的代码
private void CheckOrder()
{
Console.WriteLine("需求变化要在订单前校验");
}
private void WriteLOg()
{
Console.WriteLine("需求变化要在提交订单后添加之日");
}
#endregion
}
}
namespace ConsoleApplication6.zzl
{
/// <summary>
/// 我们的业务核心接口
/// </summary>
public interface IOrderInf
{
void GetOrderLIst();
void SubmitOrder();
}
}
namespace ConsoleApplication6.zzl
{
/// <summary>
/// 实现接口的核心业务
/// </summary>
public class OrderImpl:IOrderInf
{
public void GetOrderLIst()
{
Console.WriteLine("返回获取的订单");
}
public void SubmitOrder()
{
Console.WriteLine("提交订单接口");
}
}
}
=========================================================================
14. 《代理模式》Proxy
/// 这是我们的代理模式,
/// 1:代理模式必须继续要代理核心代码的接口
/// 2:代理模式是通过类的组合实现的,依赖性更高
/// 3:代理模式和装饰器模式的区别在于(类的组合形式不同), 装饰器模式是聚合,装饰对象是
/// 外部传递初始化的(主要是因为装饰器模式是为了做原核心代码业务改变的实现),而代理模式
/// 类的关系是组合形式,不需要外部初始化(主要是因为代理模式的主要功能是,隔离保护核心代码,控制外部对核心代码的调用,当然也可以扩展功能)
【1】概念:为客户端使用一种代理对象,以便达到对原始业务对象调用的“控制”。也就是说在原始对象的基础上,做一层
包装,通过这个包装可以“隐藏”或“限制”原始对象某些行为的直接访问、或者扩展原有行为的业务!
【2】防火墙
【3】优点:可以动态扩展原有对象的业务、并且增加相关的控制(比如封闭了某些公开的业务)
【4】应用举例:
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
//代理模式主要是做控制外部对核心代码的访问,当然也可以扩展
Console.WriteLine("---------------代理模式------------------------");
IOrderInf myorder = new ProxyOrder();
myorder.SubmitOrder();
Console.Read();
}
}
}
namespace ConsoleApplication7.zzl
{
/// <summary>
/// 这是我们的代理模式,
/// 1:代理模式必须继续要代理核心代码的接口
/// 2:代理模式是通过类的组合实现的,依赖性更高
/// 3:代理模式和装饰器模式的区别在于(类的组合形式不同), 装饰器模式是聚合,装饰对象是
/// 外部传递初始化的(主要是因为装饰器模式是为了做原核心代码业务改变的实现),而代理模式
/// 类的关系是组合形式,不需要外部初始化(主要是因为代理模式的主要功能是,隔离保护核心代码,控制外部对核心代码的调用,当然也可以扩展功能)
/// </summary>
public class ProxyOrder:IOrderInf
{
private IOrderInf myorder;
#region 核心接口代码
public ProxyOrder()
{
this.myorder = new OrderImpl();
}
public void GetOrderLIst()
{
}
public void SubmitOrder()
{
//安装业务变化在订单前校验
CheckOrder();
this.myorder.SubmitOrder();
//根据业务变化在提交订单后添加日志
WriteLOg();
}
#endregion
#region 我们业务变化需要修改的代码
private void CheckOrder()
{
Console.WriteLine("需求变化要在订单前校验");
}
private void WriteLOg()
{
Console.WriteLine("需求变化要在提交订单后添加之日");
}
#endregion
}
}
namespace ConsoleApplication6.zzl
{
/// <summary>
/// 我们的业务核心接口
/// </summary>
public interface IOrderInf
{
void GetOrderLIst();
void SubmitOrder();
}
}
namespace ConsoleApplication7.zzl
{
/// <summary>
/// 实现接口的核心业务
/// </summary>
public class OrderImpl:IOrderInf
{
public void GetOrderLIst()
{
Console.WriteLine("返回获取的订单");
}
public void SubmitOrder()
{
Console.WriteLine("提交订单接口");
}
}
}
=========================================================================
装饰器模式和代理模式的区别:
相同点:装饰者(decorator)和被装饰者(decoratee)都是实现同一个接口。代理类(proxy class)和真实处理的类
(real class)都实现同一个接口。两种设计模式都可以很容易的在真实的对象方法前面或后面加上自定义的方法!
不同点【1】装饰器模式专注的是“在一个对象上面动态的增加方法”。做法是将“原对象作为参数传给装饰者构造方法”。
不同点【2】代理模式专注于“控制对象的访问”。换句话说,代理类可以对它的调用者隐藏一个对象的具体信息。
做法是将“在一个代理类中创建一个具体对象的实例”。
总结:使用代理模式,代理和真实对象之间的关系通常在编译时就已经确定了。而装饰器模式在运行时依次构造出来的。
构造顺序:装饰者-->装饰器
=========================================================================