模式概念:
允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
使用场景:
1.如果你希望在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为, 可以使用装饰模式。
2.如果用继承来扩展对象行为的方案难以实现或者根本不可行, 你可以使用该模式。
代码样例
代码背景: 装饰者模式主要是使用聚合方式对方法进行增强,比如有个通知系统在发生重要事情的给你发送告知信息,一开始是发送邮件,后来你想在发送邮件的同时通过QQ也发送一条消息,另一个人希望在发送邮件的同时通过微信也发送一条消息,那么可以新增QQ、微信类,继承自之前的通知类来实现目标,但是还有一部分人希望同时发送邮件、QQ、微信消息,那么就需要在新建一个特殊的子类来实现;对应这种发送方式间的组合如果使用继承来实现会导致类爆炸,解决方式是使用聚合方式。以下代码是一个人的会面行为进行方法增强的装饰者模式代码样例:
/**
* 用户实体
*/
public class UserInfo {
private String id;//ID
private String name;//名称
private String sex;//性别
private String clothes;//衣服
private String Lipstick;//口红
private String earStuds;//耳钉
private String bag;//包包
public UserInfo(String id,String name,String sex){
this.id = id;
this.name = name;
this.sex = sex;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getClothes() {
return clothes;
}
public void setClothes(String clothes) {
this.clothes = clothes;
}
public String getLipstick() {
return Lipstick;
}
public void setLipstick(String lipstick) {
Lipstick = lipstick;
}
public String getEarStuds() {
return earStuds;
}
public void setEarStuds(String earStuds) {
this.earStuds = earStuds;
}
public String getBag() {
return bag;
}
public void setBag(String bag) {
this.bag = bag;
}
@Override
public String toString() {
return "UserInfo{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", clothes='" + clothes + '\'' +
", Lipstick='" + Lipstick + '\'' +
", earStuds='" + earStuds + '\'' +
", bag='" + bag + '\'' +
'}';
}
/**
* 用户行为接口
*/
public interface UserInfoService {
public void eat(UserInfo info);
public void sleep(UserInfo info);
public void meet(UserInfo info);
}
/**
* 用户行为实现类
*/
public class UserInfoServiceImpl implements UserInfoService {
@Override
public void eat(UserInfo info) {
System.out.println(info.getName()+"吃了5斤米饭");
}
@Override
public void sleep(UserInfo info) {
System.out.println(info.getName()+"一觉睡了300年");
}
@Override
public void meet(UserInfo info) {
System.out.println("meet行为最终结果:"+info.getName()+"与人会面,装着详情:"+info.toString());
}
}
/**
* 装饰者基类
*/
public class BaseDecorator implements UserInfoService{
private UserInfoService userInfoService;//封装对象
public BaseDecorator(UserInfoService userInfoService){
this.userInfoService = userInfoService;
}
@Override
public void eat(UserInfo info) {
userInfoService.eat(info);
}
@Override
public void sleep(UserInfo info) {
userInfoService.sleep(info);
}
/**
* 观察者按需对方法进行“增强”
*/
@Override
public void meet(UserInfo info) {
if(info.getClothes() == null){
System.out.println(" 基础装饰者在会客前给穿件衣服");
info.setClothes("西装");
}
userInfoService.meet(info);
}
}
/**
* 服装装饰者
*/
public class ClothesDecorator extends BaseDecorator{
public ClothesDecorator(UserInfoService userInfoService) {
super(userInfoService);
}
/**
* 装饰者对方法增强
*/
@Override
public void meet(UserInfo userInfo){
System.out.println("衣服装饰者:");
System.out.println(" 衣服装饰者给穿个花衣服");
userInfo.setClothes("黑丝");
super.meet(userInfo);
}
}
/**
* 口红装饰者
*/
public class EarStudsDecorator extends BaseDecorator{
public EarStudsDecorator(UserInfoService userInfoService) {
super(userInfoService);
}
/**
* 装饰者对方法增强
*/
@Override
public void meet(UserInfo userInfo){
System.out.println("口红装饰者:");
System.out.println(" 涂口红不方便吃饭,先吃个饭在涂口红");
super.eat(userInfo);
System.out.println(" 吃完饭口红装饰者给图个口红");
userInfo.setEarStuds("烈焰红唇");
super.meet(userInfo);
}
}
/**
* 耳钉装饰者
*/
public class LipStickDecorator extends BaseDecorator{
public LipStickDecorator(UserInfoService userInfoService) {
super(userInfoService);
}
/**
* 装饰者对方法增强
*/
@Override
public void meet(UserInfo userInfo){
System.out.println("耳钉装饰者:");
System.out.println(" 耳钉装饰者给带个耳钉");
userInfo.setLipstick("七连环耳钉");
super.meet(userInfo);
}
}
/**
* 包包装饰者
*/
public class BagDecorator extends BaseDecorator{
public BagDecorator(UserInfoService userInfoService) {
super(userInfoService);
}
/**
* 装饰者对方法增强
*/
@Override
public void meet(UserInfo userInfo){
System.out.println("包包装饰者:");
System.out.println(" 包包装饰着给背个包包");
userInfo.setBag("爱马仕至尊限量版包包");
super.meet(userInfo);
}
}
public class TestDecorator {
public static void main(String[] args) {
System.out.println("场景1:杨贵妃要不远万里去见她的男朋友,她需要精心打扮一番,穿上花衣服,化个美美妆");
UserInfo yang = new UserInfo("001","杨贵妃","女");
UserInfoService yangService = new ClothesDecorator(new BagDecorator(
new EarStudsDecorator(new LipStickDecorator(new UserInfoServiceImpl()))));
yangService.meet(yang);
System.out.println();
System.out.println();
System.out.println();
System.out.println("场景2:西施下午公司有个会议要参加,简单化个妆");
UserInfo xi = new UserInfo("002","西施","女");
UserInfoService xiservice = new LipStickDecorator(new UserInfoServiceImpl());
xiservice.meet(xi);
}
}
测试结果: