返回

架构师面试必备:彻底搞懂装饰器、代理和适配器模式!

Android

装饰器、代理和适配器模式:彻底区分三大设计模式!

装饰器模式

想象场景: 你需要为你的对象增添额外的功能,就好像给它们穿上不同的衣服一样,每件衣服都能赋予它们新的能力。

解决办法: 装饰器模式!它允许你在不修改对象源代码的情况下,向其添加新的功能。就好比你给一个基本对象穿上不同的“装饰器”,赋予它额外的能力。

代理模式

想象场景: 你需要一个中间人来控制对目标对象的访问,就像一个看门人一样,它负责批准或拒绝对对象的访问请求。

解决办法: 代理模式!它创建了一个代理对象来控制对目标对象的访问,可以用来限制访问次数、记录日志等。就好比你聘请了一个“代理人”来管理对某个名人或高价值对象的访问。

适配器模式

想象场景: 你有两个不兼容的接口,就好像使用不同语言的两个人一样,他们需要一个翻译器才能交流。

解决办法: 适配器模式!它创建了一个适配器对象来转换一个对象的接口,使其与另一个对象兼容。就好比你聘请了一个“翻译器”来调解两个说不同语言的人之间的交流。

三大模式的差异

虽然这三个模式都是结构型设计模式,但它们在用途和实现方式上存在着差异:

  • 用途: 装饰器用于添加功能,代理用于控制访问,适配器用于转换接口。
  • 实现方式: 装饰器通过继承或组合实现,代理和适配器通过委托实现。
  • 动态性: 装饰器可以动态改变对象行为,而代理和适配器只能静态改变。

代码示例

装饰器模式:

interface Person {
    void eat();
}

class NormalPerson implements Person {
    @Override
    public void eat() {
        System.out.println("Eating normally...");
    }
}

class DecoratedPerson implements Person {
    private Person person;

    public DecoratedPerson(Person person) {
        this.person = person;
    }

    @Override
    public void eat() {
        person.eat();
        System.out.println("Eating with extra sauce...");
    }
}

代理模式:

interface Service {
    void doSomething();
}

class ServiceImpl implements Service {
    @Override
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

class ProxyService implements Service {
    private Service service;

    public ProxyService(Service service) {
        this.service = service;
    }

    @Override
    public void doSomething() {
        System.out.println("ProxyService: Before calling doSomething()");
        service.doSomething();
        System.out.println("ProxyService: After calling doSomething()");
    }
}

适配器模式:

interface OldSystem {
    void doSomethingOld();
}

class OldSystemImpl implements OldSystem {
    @Override
    public void doSomethingOld() {
        System.out.println("Doing something old...");
    }
}

interface NewSystem {
    void doSomethingNew();
}

class Adapter implements NewSystem {
    private OldSystem oldSystem;

    public Adapter(OldSystem oldSystem) {
        this.oldSystem = oldSystem;
    }

    @Override
    public void doSomethingNew() {
        oldSystem.doSomethingOld();
    }
}

常见问题解答

  1. 这三个模式哪一个最好?

    • 没有一个“最好的”模式,每个模式都有自己的特定用途。
  2. 它们可以一起使用吗?

    • 是的,它们可以根据需要组合使用。
  3. 我可以创建一个自定义的结构型设计模式吗?

    • 是的,你可以创建自己的模式来解决特定问题。
  4. 这些模式对我的项目有什么好处?

    • 它们可以提高代码的可重用性、可扩展性和可维护性。
  5. 它们在哪些行业中使用?

    • 它们广泛用于软件开发的所有行业。