想说的话:
在大学的时候曾经学过这23种设计模式,但是那时没啥编程经验,糊里糊涂过了一遍,没多久就忘记了,工作之后将精力主要集中在学习新技术上,比如springboot,cloud,docker,vue。毕业两年后去面试,发现设计模式还是java程序员需要迈过的一道坎,面试的时候问到代理模式和适配器模式有什么区别,你在工作中用到了什么设计模式,怎么用的?答不上来的特别尴尬,所以决定重新学习这几种设计模式,争取在工作中使用上。
本文所有案例代码
码云:https://gitee.com/helloworld6379/designPattern
Github:Github地址
1 设计模式是程序员在面对同类软件工程设计问题所总结出来的有用的经验,模式不是代码,而是某类问题的通
用解决方案,设计模式(Design pattern)代表了最佳的实践。这些解决方案是众多软件开发人员经过相当长的
一段时间的试验和错误总结出来的。
2 设计模式的本质提高 软件的维护性,通用性和扩展性,并降低软件的复杂度。
3 设计模式并不局限于某种语言,java,php,c++ 都有设计模式.
设计模式类型
设计模式分为三种类型,共 23 种
1 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式。
2 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
3 行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter 模式)、状态模式、策略模式、职责链模式(责任链模式)。
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
主要解决:扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
何时使用:在不想增加很多子类的情况下扩展类。
如何解决:将具体功能职责划分,同时继承装饰者模式。
关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。
使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。
创建手机接口(Phone)和两个实现了接口的实体类华为手机(HuaWeiPhone)和小米手机(XiaoMiPhone)。实体类实现了手机的基本功能打电话。
然后创建一个实现了 Phone接口的抽象装饰类 PhoneDecorator,并把 Phone对象作为它的实例变量。
WeChatCallDecorator是实现了 PhoneDecorator的实体类,内部添加了微信打电话功能。
/**
* @Description 手机接口,有手机最基本的打电话功能
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public interface Phone {
public void call();
}
/**
* @Description 华为手机有打电话功能
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class HuaWeiPhone implements Phone {
@Override
public void call() {
System.out.println("华为手机可以打电话。");
}
}
/**
* @Description 小米手机有打电话功能
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class XiaoMiPhone implements Phone {
@Override
public void call() {
System.out.println("小米手机可以打电话。");
}
}
/**
* @Description 抽象角色,不实现任何功能
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public abstract class PhoneDecorator implements Phone{
protected Phone phone;
public PhoneDecorator(Phone phone){
this.phone = phone;
}
public void call(){
phone.call();
}
}
/**
* @Description 重新父类方式,扩展功能
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class WeChatCallDecorator extends PhoneDecorator {
public WeChatCallDecorator(Phone phone) {
super(phone);
}
@Override
public void call() {
phone.call();
weChatCall(phone);
}
public void weChatCall(Phone phone){
System.out.println("手机可以微信打电话了");
}
}
/**
* @Description 装饰者模式测试
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class DecoratorTest {
public static void main(String[] args) {
Phone xiaomiPhone = new XiaoMiPhone();
PhoneDecorator xiaomiPhoneP = new WeChatCallDecorator(new XiaoMiPhone());
PhoneDecorator huaWeiPhoneP = new WeChatCallDecorator(new HuaWeiPhone());
xiaomiPhone.call();
xiaomiPhoneP.call();
huaWeiPhoneP.call();
}
}
Java 的 IO 结构,FilterInputStream 就是一个装饰者
InputStream 是抽象类, 类似案例的Phone
FileInputStream 是 InputStream 子类,类似HuaWeiPhone和XiaoMiPhone
FilterInputStream 是 InputStream 子类:类似 PhoneDecorator
DataInputStream 是 FilterInputStream 子类,具体的修饰者,类似WeChatCallDecorator
FilterInputStream 类 有 protected volatile InputStream in; 即含被装饰者
DataInputStream dis = new DataInputStream(new FileInputStream("D:\\test.txt"));
System.out.println(dis.read());
dis.close();