小菜成长记(三)--装饰者模式

本文介绍了一种使用装饰模式实现角色装扮的功能,通过不同类的组合实现了动态添加装扮的效果,解决了传统方式下添加新装扮需要频繁修改代码的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写一个简单的角色装扮代码:
public class Program {
    public static void main(String[] args) {
        Person person = new Person("小菜");
        System.out.println("第一种装扮");
        person.wearTShirts();
        person.wearBigTrouser();
        System.out.println("第二种装扮");
        person.wearSuits();
        person.wearLeaherShoes();
    }
}

class Person{
    private String name;


    public Person(String name) {
        this.name = name;
    }

    public void wearTShirts(){
        System.out.println("大T恤 ");
    }

    public void wearBigTrouser(){
        System.out.println("垮裤");
    }

    public void wearSuits(){
        System.out.println("西装");
    }

    public void wearLeaherShoes(){
        System.out.println("穿皮鞋");
    }
}
问题来了:如果我们增加一个装饰,就要修改很多代码,上面的代码不符合我们的开发闭合原则:面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。
public class Program {
    public static void main(String[] args) {
        Person person = new Person("小菜");
        TShirtsFinery tShirts = new TShirtsFinery();
        BigTrouserFinery bigTrouser = new BigTrouserFinery();
        System.out.println("第一种装扮");
        tShirts.show();
        bigTrouser.show();

        SuitsFinery suits = new SuitsFinery();
        LeaherShoesFinery leaherShoes = new LeaherShoesFinery();
        System.out.println("第二种装扮");
        suits.show();
        leaherShoes.show();
    }
}

class Person {
    private String name;

    public Person(String name){
        this.name = name;
    }
}

abstract class Finery{
    public abstract void show();
}

class TShirtsFinery extends Finery {
    @Override
    public void show() {
        System.out.println("大T恤 ");
    }
}

class BigTrouserFinery extends Finery {
    @Override
    public void show() {
        System.out.println("垮裤 ");
    }
}

class SuitsFinery extends Finery {
    @Override
    public void show() {
        System.out.println("西装 ");
    }
}

class LeaherShoesFinery extends Finery {
    @Override
    public void show() {
        System.out.println("穿皮鞋 ");
    }
}
问题来了:上面的代码不够封闭,我们想要其中一种装扮,就要暴露很多方法,每个装饰相互间的联系应该封装起来,我们要采用装饰设计模式。
public class Program {
    public static void main(String[] args) {
        Person person = new Person("小菜");
        TShirtsFinery tShirts = new TShirtsFinery();
        BigTrouserFinery bigTrouser = new BigTrouserFinery();
        System.out.println("第一种装扮");
        tShirts.decorate(person);
        bigTrouser.decorate(tShirts);
        bigTrouser.show();

        SuitsFinery suits = new SuitsFinery();
        LeaherShoesFinery leaherShoes = new LeaherShoesFinery();
        System.out.println("第二种装扮");
        suits.decorate(person);
        leaherShoes.decorate(suits);
        leaherShoes.show();
    }
}
class Person {
    private String name;
    public Person(){ }

    public Person(String name){
        this.name = name;
    }

    public void show(){
        System.out.println("装扮的" + name);
    }
}

class Finery extends Person{
    protected Person component;
    public void decorate(Person component) {
        this.component = component;
    }

    @Override
    public void show() {
        if (component != null) {
            component.show();
        }
    }
}

class TShirtsFinery extends Finery {
    @Override
    public void show() {
        System.out.println("大T恤 ");
        super.show();
    }
}

class BigTrouserFinery extends Finery {
    @Override
    public void show() {
        System.out.println("垮裤 ");
        super.show();
    }
}

class SuitsFinery extends Finery {
    @Override
    public void show() {
        System.out.println("西装 ");
        super.show();
    }
}

class LeaherShoesFinery extends Finery {
    @Override
    public void show() {
        System.out.println("穿皮鞋 ");
        super.show();
    }
}
个人总结;装饰模式是为已有功能动态地添加更多功能的一种方式。什么时候用呢?当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值