在上一篇策略模式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'