装饰器(修饰)模式
一、什么是装饰(修饰)模式
装饰器(Decorator):动态地给一个对象添加一些额外的职责。
打个比方:老王是个打工人,穿上格子衫当程序员,黄袍加身当上美团配送员,穿上睡衣当宅男。老王就是一个纯粹的人,格子衫、黄袍、睡衣是能给他不同的工作属性。
改变老王的属性只需要给他穿不同的衣服(修饰器),就能有不同的功能
二、 优缺点
优点:装饰器与被装饰的组件功能独立,降低耦合度,拆卸、组装自由。
缺点:多个装饰器嵌套出问题的时候要层层排查。
三、场景例子
- Java Spring MVC 中使用 @RequestMapping 来映射请求方法路径。
@Controller
public class UserController {
@RequestMapping("/login")
public String login(String account,String passward) {
return "success";
}
}
如上,客户端可以通过 /login
来访问这个方法实现登陆。我们只需要处理登录的逻辑,至于怎么获取参数、怎么实现Serverlet则是注解实现了。
- Web React antd form ,antd的form表单校验修饰器:
import { Form, Icon, Input, Button } from 'antd';
const FormItem = Form.Item;
function hasErrors(fieldsError) {
return Object.keys(fieldsError).some(field => fieldsError[field]);
}
const rules = [{ required: true, message: 'Please input your username!' }];
@Form.create()
class LoginForm extends React.Component {
handleSubmit = (e) => {
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('校验通过!';
}
});
}
render() {
const { getFieldDecorator } = this.props.form;
const userNameError = getFieldError('userName');
return (
<Form layout="inline" onSubmit={this.handleSubmit}>
<FormItem >
{getFieldDecorator('userName', {
rules: rules,
})(
<Input placeholder="Username" />
)}
</FormItem>
<FormItem>
<Button
type="primary"
onClick={this.handleSubmit}
>
登陆
</Button>
</FormItem>
</Form>
);
}
}
如上,我们加上修饰器的登录框组件就有了修饰器提供的一系列方法,如this.props.form.validateFields
。里面的getFieldDecorator
也用了修饰器模式,给输入框加入校验规则等,使其有了校验功能。
四、代码实现
// 美团外卖修饰器
const WMDecoration = target =>{
// 这样写会污染原型链,可以考虑“继承”等的方式,先简单写
target.prototype.sendWm = () => console.log("送外卖")
return target;
}
// 写代码修饰器
const CoderDecoration = target =>{
target.prototype.code = () => console.log("写代码")
return target;
}
// 老王
function LaoWang(){
this.eat = () => console.log("吃饭")
}
// 老王学会了送外卖
LaoWang = WMDecoration(LaoWang)
// 老王学会了写代码
LaoWang = CoderDecoration(LaoWang)
const man = new LaoWang();
man.eat();// 吃饭
man.sendWm(); // 送外卖
man.code(); // 写代码
JS代码实现可以参考:
https://blog.csdn.net/xiaolongbaobushibao/article/details/82979146
Java 代码实现可以参考
https://www.runoob.com/design-pattern/decorator-pattern.html