装饰者模式学习与使用以及优缺点

在上一篇策略模式https://blog.youkuaiyun.com/minyunfei6/article/details/130666111的基础上,我们来学习装饰者模式,基于之前的女娲造人的功能,女娲可以造男人、女人、机器人;现在我们想让女娲造人的时候可以指定这个人的颜值、身高、体重和国家等,可以指定这四项里的一项或多项;

在这里插入图片描述

1. 首先我们来创建Person抽象组件类
/**
 1. @Author: myf
 2. @CreateTime: 2023-05-14 11:36
 3. @Description: Person 抽象组件
 */
public abstract class Person {

    /**
     * 获取人的方法
     * 
     * @return
     */
    abstract String getPerson();

    /**
     * 获取对人的描述的方法
     * 
     * @return
     */
    String getDescription() {
        return getPerson();
    };
}
2. 我们来创建抽象组件类的子类,具体组件。
/**
 * @Author: myf
 * @CreateTime: 2023-05-14 11:38
 * @Description: 具体组件
 */
public class PersonMan extends Person {
    @Override
    public String getPerson() {
        return "男人生产出来了 ";
    }

}
/**
 * @Author: myf
 * @CreateTime: 2023-05-14 11:39
 * @Description: 具体组件
 */
public class PersonWoman extends Person {
    @Override
    public String getPerson() {
        return "女人生产出来了 ";
    }
}
/**
 1. @Author: myf
 2. @CreateTime: 2023-05-14 11:40
 3. @Description: 具体组件
 */
public class PersonRobot extends Person {
    @Override
    public String getPerson() {
        return "机器人生产出来了 ";
    }
}
3. 接着我们按图示那样来创建抽象装饰者,体征类。
/**
 1. @Author: myf
 2. @CreateTime: 2023-05-14 11:40
 3. @Description: 抽象装饰者
 */
public abstract class Sign extends Person {
    private Person person;

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

    /**
     * 获取体征
     * 
     * @param
     * @return
     */
    abstract String getSigns();

    /**
     * 设置国家
     * 
     * @param country
     * @return
     */
    abstract void setCountry(String country);

    @Override
    String getPerson() {
        return person.getPerson();
    }

    /**
     * 重写描述方法
     * 
     * @return
     */
    @Override
    String getDescription() {
        return person.getDescription() + getSigns();
    }
}
4. 最后我们来创建抽象装饰者的子类,具体装饰者。
/**
 * @Author: myf
 * @CreateTime: 2023-05-14 12:12
 * @Description: 具体装饰者
 */
public class FaceValueSign extends Sign {
    private Person person;
    private double sign;
    private String country;

    public FaceValueSign(Person person, double sign) {
        super(person);
        this.person = person;
        this.sign = sign;
    }

    @Override
    public String getSigns() {
        // 这里可以对初始的颜值sign进行处理
        return " 颜值是:" + sign;
    }

    @Override
    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    String getDescription() {
        return StringUtils.isBlank(country) ? person.getDescription() + getSigns()
            : person.getDescription() + country + getSigns();
    }
}
/**
 * @Author: myf
 * @CreateTime: 2023-05-14 11:48
 * @Description: 具体装饰者
 */
public class HeightSign extends Sign {
    private Person person;
    private double sign;
    private String country;

    public HeightSign(Person person, double sign) {
        super(person);
        this.person = person;
        this.sign = sign;
    }

    @Override
    public String getSigns() {
        // 这里可以对初始的sign进行处理
        return " 身高为" + sign;
    }

    @Override
    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    String getDescription() {
        return StringUtils.isBlank(country) ? person.getDescription() + getSigns()
            : person.getDescription() + country + getSigns();
    }
}
/**
 1. @Author: myf
 2. @CreateTime: 2023-05-14 12:00
 3. @Description: 具体装饰者
 */
public class WeightSign extends Sign {
    private Person person;
    private double sign;
    private String country;

    public WeightSign(Person person, double sign) {
        super(person);
        this.person = person;
        this.sign = sign;
    }

    @Override
    public String getSigns() {
        // 这里可以对初始的体重sign进行处理
        return " 体重为" + sign;
    }

    @Override
    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    String getDescription() {
        return StringUtils.isBlank(country) ? person.getDescription() + getSigns()
            : person.getDescription() + country + getSigns();
    }
}
5. 都创建好之后,我们来实际调用一下看看。
/**
 * @Author: myf
 * @CreateTime: 2023-05-14 12:18
 * @Description: PersonClient
 */
public class PersonClient {

    public static void main(String[] args) {
        Person personWoman = new PersonWoman();
        System.out.println(personWoman.getDescription());

        personWoman = new FaceValueSign(personWoman, 8.0);
        System.out.println(personWoman.getDescription());

        HeightSign heightSignWoman = new HeightSign(personWoman, 165.4);
        heightSignWoman.setCountry("中国");
        System.out.println(heightSignWoman.getDescription());

        WeightSign weightSign = new WeightSign(heightSignWoman, 90.0);
        System.out.println(weightSign.getDescription());
    }
}

执行结果

Connected to the target VM, address: '127.0.0.1:64328', transport: 'socket'
女人生产出来了 
女人生产出来了  颜值是:8.0
女人生产出来了  颜值是:8.0中国 身高为165.4
女人生产出来了  颜值是:8.0中国 身高为165.4 体重为90.0
Disconnected from the target VM, address: '127.0.0.1:64328', transport: 'socket'

6. 可以看到实际调用时很灵活,女人、男人、机器人可以和身高、体重、颜值、国家自由组合。如果后面再增加其它属性,比如造人时指定智商,那我们不需要修改现有代码,只需要增加一个IQSign,需要指定智商时,只需要new IQSign即可,结构很清晰。缺点就是使用装饰者代码量会增加,增加程序的运行时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值