大话设计模式——装饰模式和代理模式(一)

痛定思痛。 2021-09-30 14:50 451阅读 0赞

1、是什么?

装饰模式:动态地给一个对象添加额外的职责。

923564-20181017202340451-411391662.png

代理模式:其他对象通过对象A去访问对象B。

923564-20181017202400465-176750854.png

2、为什么用?

装饰模式:1、遵循开闭原则,尽量不去修改原有的类。2、装饰对象一般都是添加额外的非核心功能,通过继承来扩展也可以达到目的,不过无法灵活的组合这些新添的功能。

代理模式:假如一个对象A有很多方法,但是对于某些对象只允许访问A中一部分方法,这就需要通过代理对象进行访问,这就是所谓的权限。==

3、怎么用?

装饰模式:

  1. public class task_02_装饰模式 {
  2. @Test
  3. public void test() {
  4. Client client=new Client();
  5. RealPerson person1=new RealPerson("小强");
  6. client.fun(person1);
  7. BasePerson person2=new Decorator1(person1);
  8. client.fun(person2);
  9. BasePerson person3=new Decorator2(person1);
  10. client.fun(person3);
  11. }
  12. }
  13. class Client{
  14. public void fun(BasePerson person) {
  15. person.play();
  16. }
  17. }
  18. /**
  19. * 对象接口,对其play方法进行装饰
  20. * @author xiang20180825
  21. *
  22. */
  23. interface BasePerson{
  24. void play();
  25. }
  26. /**
  27. * 具体对象
  28. * @author xiang20180825
  29. *
  30. */
  31. class RealPerson implements BasePerson{
  32. private String name;
  33. RealPerson(String name){
  34. this.name=name;
  35. }
  36. public void play() {
  37. System.out.println(name+"打篮球");
  38. }
  39. }
  40. /**
  41. * 装饰抽象类
  42. * @author xiang20180825
  43. *
  44. */
  45. abstract class Decorator implements BasePerson{
  46. BasePerson person;//包装了对象
  47. Decorator(BasePerson person){
  48. this.person=person;
  49. }
  50. public abstract void play();
  51. }
  52. class Decorator1 extends Decorator{
  53. Decorator1(BasePerson person){
  54. super(person);
  55. }
  56. public void play() {
  57. System.out.print("没有穿衣服的");
  58. person.play();
  59. }
  60. }
  61. class Decorator2 extends Decorator{
  62. Decorator2(BasePerson person){
  63. super(person);
  64. }
  65. public void play() {
  66. System.out.print("穿了衣服的");
  67. person.play();
  68. }
  69. }

代理模式:

  1. /*
  2. * 老板的亲戚来了,让老板给他买个早饭,老板买了。
  3. * 实际上是让助理买的,老板的亲戚根本都不知道助理的存在,也不可能让助理跳舞。
  4. *
  5. * 这里boss相当于代理类。而assistant是实际的买早点的对象。
  6. */
  7. public class task_01_代理模式 {
  8. @Test
  9. public void test() {
  10. Assistant assistant=new Assistant();
  11. Boss boss=new Boss(assistant);
  12. goShopping(boss);
  13. }
  14. public void goShopping(GoShopping goShopping) {
  15. goShopping.shopping();
  16. }
  17. }
  18. interface GoShopping{
  19. void shopping();
  20. }
  21. class Assistant implements GoShopping{
  22. public void shopping() {
  23. System.out.println("买个早点");
  24. }
  25. public void dancing() {
  26. System.out.println("跳舞");
  27. }
  28. }
  29. class Boss implements GoShopping{
  30. Assistant assistant;
  31. Boss(Assistant assistant){
  32. this.assistant=assistant;
  33. }
  34. public void shopping() {
  35.      //在这里可以做一些不可描述的事情
  36. assistant.shopping();
  37.      //在这里可以做一些不可描述的事情
  38. }
  39. }

区别:(接受批评和指正)

1、侧重点不同:装饰模式强调给对象添加额外的“装饰”,被装饰对象原本的功能正常执行;代理模式强调访问对象的间接性(对实际对象的访问进行控制)。

2、对于调用者来说,装饰模式关注被装饰的对象,效果是被装饰的功能;代理模式关注访问实际对象的代理对象,不必知道实际对象的存在,目标对象的控制交给了代理对象。

思考:BasePerson应该以抽象类还是接口的形式存在?(20181018_1更)

装饰模式的结构图中,BasePerson是抽象类,代码也是写的抽象类。今天工作之余我问了一个愚蠢的问题:为了使用装饰模式,就硬给一个对象加了一个“老爸”?随后就被前辈怼了:你不就是想问继承抽象类还是实现接口吗?首先你得把区别搞清楚。

  区别:

    1、对于一个类而言,只能继承一个类;可以实现多个接口

    2、抽象类可以有具体实现的方法;接口中方法都是抽象的

    3、抽象类可以有成员变量;接口中的都是静态常量

    4、抽象类中的抽象方法,其子类可以不实现,声明为抽象类即可;接口中的方法必须实现(当接口需要添加新的方法时,所有实现类都得改)。

  相同点:

    1、都不可实例化。

    2、都可以用来实现运行时多态。

  结论:具体情况具体对待

    1、如果一个类已经有显示继承的父类,但是只需要对该类进行装饰,那么只能使用接口。

    2、如果需要对多个类进行装饰,且有相同的装饰功能,则使用抽象类,把相同部分作为实现了的方法。

    3、个人愚见:尽量使用接口(没有完美的选择)。

  反省:有时过于用生活中的逻辑去思考了,继承中的父子关系并不是真的“爸爸和儿子的关系”。

      继承:is-a,子类是父类的一种。(子类、父类确实有些迷惑性)

代理的实际含义:(20181206更)

疑惑:之前一直对于代理的实际意义不是很理解,既然代理了,为什么客户端还能直接访问目标对象呢:从代码可以看出,客户端先创建了目标对象,然后交给代理对象

解惑:代理的实际含义是把目标对象的控制交给代理对象,并没有要求客户端一定无法直接访问目标对象。

代理模式的使用场景:

1.无法或者不适合直接访问目标对象

2.在访问目标对象前后需要做一些处理。(Spring AOP)

注:

大话设计模式6.5节中的代码结构图如下:

923564-20181017203543709-1968066659.png

个人觉得不妥之处:服饰类继承了人,没有遵循里氏代换原则。

转载于:https://www.cnblogs.com/xiangguoguo/p/9807143.html

发表评论

表情:
评论列表 (有 0 条评论,451人围观)

还没有评论,来说两句吧...

相关阅读

    相关 大话设计模式代理模式

    在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。我们创建具有现有对象的对象,以便向外界提供功能接口。 大话设计模式中程

    相关 大话设计模式装饰模式

    装饰模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创