本篇是设计模式系列的第四篇,虽然以前也写过相应的文章,可是由于种种缘由后来断掉了,并且发现以前写的内容也很渣,不够系统。
因此如今打算重写,加上距离如今也有一段时间了,也算是本身的一个回顾吧!
设计模式不是语法,是一种巧妙的写法,能把程序变的更加灵活。架构模式比设计模式大,架构模式是战略,而设计模式是战术。
设计模式分为3大类型:建立型,行为型,结构型,总共有23种。
装饰模式(Decorator)指的是在没必要改变类文件和使用继承的状况下,动态地扩展一个对象的功能。它是经过建立一个包装对象,也就是装饰来包裹真实的对象。
这种模式建立了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
公司接到一个任务,须要为某平台开发一个搭配不一样服饰的小项目,好比相似QQ、网络游戏或论坛都有的Avatar系统(为了简化代码,直接使用控制台模拟)。
通过公司的慎重讨论(实际就几秒钟),开发这一个项目的重任,又当仁不让的被产品经理交给了我,我:脸上笑嘻嘻,内心MMP。发一下下的小牢骚,不过仍是抓紧干活。
思索一下,该系统要为不一样的人进行装扮,因此定义一我的的类,不用每次装扮其余人时修改该类的代码。
而后人身上要有不少的服饰,好比:大T恤、垮裤、鞋子等等,而后穿上以后,须要展现出来。因此这里的话,能够抽象出一个服饰的基类,而后各个具体的服饰都继承该基类便可。
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public void show() {
System.out.println("装扮者:" + name);
}
}复制代码
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Finery extends Person {
protected Person component;
/**
* 打扮
* @param component
*/
public void decorate(Person component){
this.component = component;
}
@Override
public void show() {
if(null != component){
component.show();
}
}
}复制代码
/**
* @author: LKP
* @date: 2019/2/16
*/
public class TShirts extends Finery {
@Override
public void show() {
System.out.println("大T恤");
}
}
class BigTrouser extends Finery {
@Override
public void show() {
System.out.println("垮裤");
}
}
class Sneakers extends Finery{
@Override
public void show() {
System.out.println("破球鞋");
}
}
class LeatherShoes extends Finery{
@Override
public void show() {
System.out.println("皮鞋");
}
}
class Tie extends Finery{
@Override
public void show() {
System.out.println("领带");
}
}
class Suit extends Finery{
@Override
public void show() {
System.out.println("西装");
}
}复制代码
这里内部类,只是为了较少代码量,实际开发中可不要偷懒,按实际来建立。
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Main {
public static void main(String[] args) {
Person person = new Person("孤独键客");
System.out.println("第一种装扮:");
Finery tShirts = new TShirts();
Finery bigTrouser = new BigTrouser();
Finery sneakers = new Sneakers();
tShirts.show();
bigTrouser.show();
sneakers.show();
person.show();
System.out.println("\n第二种装扮:");
Finery suit = new Suit();
Finery tie = new Tie();
Finery leatherShoes = new LeatherShoes();
suit.show();
tie.show();
leatherShoes.show();
person.show();
}
}复制代码
搞定收工,审视一下,自我感受还算不错,若是新装扮只需改变一下调用顺序便可,若是又新人物,只需从新new一个Person类就能够了。
接下里将项目提交上传,而后告诉leader一声,over,离下班时间还早,好像还能够作点其余的事情~。
正当你准备打开去干点其余事情,leader回复你了:
leader:“你仔细看看这段代码,这样写意味着什么?
你想象一下,是否是把‘大T恤’、‘垮裤’、‘破球鞋’、‘装扮者’一个一个词显示出来,是否是至关于你光着身子,一个一个把这些穿上,这可有点像脱衣舞哦~”。
我:“你意思是,这些应该都在内部组装完毕,而后在显示出来?”。
leader:"宾果,并且还要按照正确的顺序串联起来控制,这里有点难度,修改好以后再给我"。
这彷佛和某种设计模式有关,难道是建造者模式吗?不对,建造者模式要求建造的过程必须是稳定的,而这个穿搭的过程是不固定的,一个有个性的人又无数种方案。
/**
* @author: LKP
* @date: 2019/2/16
*/
public class TShirts extends Finery {
@Override
public void show() {
System.out.println("大T恤");
super.show();
}
}
class BigTrouser extends Finery {
@Override
public void show() {
System.out.println("垮裤");
super.show();
}
}
class Sneakers extends Finery{
@Override
public void show() {
System.out.println("破球鞋");
super.show();
}
}
class LeatherShoes extends Finery{
@Override
public void show() {
System.out.println("皮鞋");
super.show();
}
}
class Tie extends Finery{
@Override
public void show() {
System.out.println("领带");
super.show();
}
}
class Suit extends Finery{
@Override
public void show() {
System.out.println("西装");
super.show();
}
}复制代码
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Main {
public static void main(String[] args) {
Person person = new Person("孤独键客");
System.out.println("第一种装扮:");
Sneakers sneakers = new Sneakers();
BigTrouser bigTrouser = new BigTrouser();
TShirts tShirts = new TShirts();
sneakers.decorate(person);
bigTrouser.decorate(sneakers);
tShirts.decorate(bigTrouser);
tShirts.show();
System.out.println("第二种装扮:");
LeatherShoes leatherShoes = new LeatherShoes();
Tie tie = new Tie();
Suit suit = new Suit();
leatherShoes.decorate(person);
tie.decorate(leatherShoes);
suit.decorate(tie);
suit.show();
}
}复制代码
光着膀子、打着领带、下身垮裤、脚上皮鞋,绝对的极具个性。
主要解决:通常的,咱们为了扩展一个类常用继承方式实现,因为继承为类引入静态特征,而且随着扩展功能的增多,子类会很膨胀。
如何解决:将具体功能职责划分,同时继承装饰者模式。
关键代码: 一、Component 类充当抽象角色,不该该具体实现。 二、修饰类引用和继承 Component 类,具体扩展类重写父类方法。
应用实例: 一、孙悟空有 72 变,当他变成"庙宇"后,他的根本仍是一只猴子,可是他又有了庙宇的功能。 二、不论一幅画有没有画框均可以挂在墙上,可是一般都是有画框的,而且其实是画框被挂在墙上。在挂在墙上以前,画能够被蒙上玻璃,装到框子里;这时画、玻璃和画框造成了一个物体。
优势:装饰类和被装饰类能够独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式能够动态扩展一个实现类的功能。
使用场景: 一、扩展一个类的功能。 二、动态增长功能,动态撤销。
欢迎关注个人公众号「程序员的成长之路」,阅读更多精彩!