什么是装饰器模式和代理模式,以及它们之间的区别?

本文详细阐述了装饰器模式和代理模式的概念、类结构及代码实现方式,并对比了两者的区别,帮助读者理解如何在Java中应用这些设计模式。

一. 装饰器模式

概念:装饰器模式就是给一个对象动态的增加一些功能,要求装饰对象被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

类结构图:

代码理解:

1.先定义一个抽象接口Sourceable

package com.sjms.decorator;

public interface Sourceable {

    //自定义抽象方法

    void method();

}

2.定义一个实现类Source 实现抽象接口Sourceable

package com.sjms.decorator;

public class Source implements Sourceable {

    @Override

    public void method() {

        System.out.println("素颜可以如此之美!");

    }

}

 

3.定义一个装饰类Decorator实现Sourceable接口,装饰类持有被装饰对象的实例

package com.sjms.decorator;

public class Decorator implements  Sourceable {

    private  Sourceable source;

    public  Decorator(Sourceable source){

        this.source=source;

    }

    @Override

    public void method() {

          source.method();//保持原功能不变

        System.out.println("化妆之后你会更美");

    }

}

4.测试

package com.sjms.decorator;

public class SourceableTest {

    public static void main(String[] args) {

        Sourceable sourceable = new Source();

        sourceable.method();       

        System.out.println("------------------------------");

        // 接下来使用装饰类实现功能

        Sourceable sourceable1 = new Decorator(sourceable);//把要装饰的实例传给装饰类

        sourceable1.method();

    }

}

实际意义:

可以实现一个类功能的扩展。 可以动态的增加功能,而且还能动态撤销(继承不行)。

缺点:产生过多相似的对象,不易排错。

(装饰器模式体现了合成复用原则)

二.代理模式

概念: 代理模式就是找一个代理类替原对象进行一些操作。 比如我们在租房子的时候找中介,再如我们打官司需要请律师,中介和律师在这里就是我们的代理。

类结构图:

代码理解:

1.先定义一个抽象接口Sourceable

package com.sjms.proxy;

public interface Sourceable {

    //自定义抽象方法

    void method();

}

2.定义一个实现类Source 实现抽象接口Sourceable

package com.sjms.proxy;

public class Source implements Sourceable {

    @Override

    public void method() {

        System.out.println("素颜可以如此之美!");

    }

}

 

3.定义一个代理类实现接口

public class Proxy implements Sourceable {

    private Source source;

    public Proxy() {

        source = new Source();

    }

    @Override

    public void method() {

        source.method();

        System.out.println("我和装饰器模式其实是不一样的!");

    }

}

 

4.测试

package com.sjms.proxy;

public class SourceableTest {

    public static void main(String[] args) {      

        System.out.println("代理模式--------");

        Sourceable sourceable2 = new Proxy();

        sourceable2.method();

    }

}

 

实际意义:

    如果在使用的时候需要对原有的方法进行改进,可以采用一个代理类调用原有方法,并且对产生的结果进行控制,这种方式就是代理模式。 使用代理模式,可以将功能划分的更加清晰,有助于后期维护。

三.代理模式和装饰器模式的区别

    装饰器模式通常的做法是将原始对象作为一个参数传给装饰者的构造器,而代理模式通常在一个代理类中创建一个被代理类的对象。 装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。(两者都是结构型设计模式)

-----随后补充在java相关技术框架,用到这两种设计模式的场景----

装饰器模式代理模式是两种结构型设计模式,它们之间区别如下: 1. 装饰器模式是在不改变原有对象结构的情况下,动态地给对象添加新的行为。也就是说,装饰器模式关注于对对象的功能扩展,而不是对象本身。 2. 代理模式则是为了控制对对象的访问,通常是因为对象具有重要的敏感信息或功能。代理对象可以在调用原始对象之前或之后执行一些操作,这种方式可以提高系统的安全性、稳定性灵活性。 下面分别给出装饰器模式代理模式的代码示例: 装饰器模式示例: ```java // 定义一个抽象组件 interface Component { void operation(); } // 具体组件类 class ConcreteComponent implements Component { @Override public void operation() { System.out.println("ConcreteComponent operation..."); } } // 抽象装饰器类 abstract class Decorator implements Component { protected Component component; public Decorator(Component component) { this.component = component; } @Override public void operation() { if (component != null) { component.operation(); } } } // 具体装饰器类A class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void operation() { super.operation(); addBehaviorA(); } private void addBehaviorA() { System.out.println("ConcreteDecoratorA added behavior A..."); } } // 具体装饰器类B class ConcreteDecoratorB extends Decorator { public ConcreteDecoratorB(Component component) { super(component); } @Override public void operation() { super.operation(); addBehaviorB(); } private void addBehaviorB() { System.out.println("ConcreteDecoratorB added behavior B..."); } } // 客户端代码 public class Client { public static void main(String[] args) { Component component = new ConcreteComponent(); Component decorator1 = new ConcreteDecoratorA(component); Component decorator2 = new ConcreteDecoratorB(decorator1); decorator2.operation(); } } ``` 代理模式示例: ```java // 抽象主题类 interface Subject { void request(); } // 具体主题类 class ConcreteSubject implements Subject { @Override public void request() { System.out.println("ConcreteSubject request..."); } } // 代理类 class ProxySubject implements Subject { private Subject subject; public ProxySubject(Subject subject) { this.subject = subject; } @Override public void request() { beforeRequest(); subject.request(); afterRequest(); } private void beforeRequest() { System.out.println("ProxySubject before request..."); } private void afterRequest() { System.out.println("ProxySubject after request..."); } } // 客户端代码 public class Client { public static void main(String[] args) { Subject realSubject = new ConcreteSubject(); Subject proxySubject = new ProxySubject(realSubject); proxySubject.request(); } } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值