DataInputStream bis = new DataInputStream(new BufferedInputStream(new FileInputStream("File")));
绥棱ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!
BufferedInputStream bis2 = new BufferedInputStream(new DataInputStream(new FileInputStream("File")));
BufferedInputStream添加了缓冲功能,请问,bis还有缓冲功能么?bis现在是DataInputStream类型的,bis2才是BufferedInputStream类型的,这是我学些IO的一个问题,为什么bis还有缓冲功能?
问题:动态给一个对象添加一些额外的职责
思考:可以修改这个类的源代码吗?
回答:可以
思考:那直接修改源代码就行了
问题:如果不可以修改呢?
思考:如果不可以修改源代码,那怎么添加?
回答:有一些类库可以直接修改编译后的class文件,但是这里不考虑
可以直接包含这个类的对象,如果这个类有实现某些接口,刚好某个需要添加额外智能的方法正好是其中一个方法,那就好办了
Son这个类的paint()方法需要添加一些额外的功能
package decorator;
public class Son implements Work {
public void paint() {
System.out.println("儿子用铅笔画好了一幅画。");
}
}
这个类不是实现了Work方法吗?那就好办了,新建一个类,继承Work接口:
package decorator;
public class Mother implements Work {
//被装饰者
private Work work;
public Mother(Work work) {
this.work = work;
}
private Mother() {}
public void paint() {
//妈妈装饰者做的职责
System.out.println("妈妈正在做给画上颜色前的准备工作。");
//被装饰者做的职责
work.paint();
//妈妈装饰者做的职责
System.out.println("妈妈给画上好了颜色。");
}
}
那个所谓的Work接口:
package decorator;
public interface Work {
public void paint();
}
你不是想让Son可以的paint方法多做点工作么?那我new出Mother类执行paint方法不就可以了吗
看代码就知道,其实这个装饰器模式并不怎么好用,每个需要装饰的类或者需要继承某个接口,这实在是一个限制
网上找的资料:
装饰模式(Decorator)
装饰模式又名包装(Wrapper)模式。
装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰模式通过创建一个包装对象,也就是装饰,来包裹真实的对象。
装饰模式以对客户端透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。
装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。
装饰模式把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展是完全透明的。
装饰模式的角色
抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件角色(Concrete Component):定义将要接收附加责任的类。
装饰角色(Decorator):持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口。
具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任。
Java IO中的装饰模式
在IO中,具体构件角色是节点流,装饰角色是过滤流。
FilterInputStream和FilterOutputStream是装饰角色,而其他派生自它们的类则是具体装饰角色。
装饰模式的特点
装饰对象和真实对象有相同的接口。这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。
装饰对象包含一个真实对象的引用(reference)。
装饰对象接收所有来自客户端的请求,它把这些请求转发给真实的对象。
装饰对象可以在转发这些请求之前或之后附加一些功能。
这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。
程序实例
public interface Component
{
public void doSomething();
}
这是抽象构件角色,是一个接口。具体构件角色实现这个接口:
public class ConcreteComponent implements Component
{
@Override
public void doSomething()
{
System.out.println("功能A");
}
}
装饰角色:
public class Decorator implements Component
{
private Component component;
public Decorator(Component component)
{
this.component = component;
}
@Override
public void doSomething()
{
component.doSomething();
}
}
其中包含了构件角色的引用,方法调用中利用构件角色的方法。
具体装饰角色(两个):
public class ConcreteDecorator1 extends Decorator
{
public ConcreteDecorator1(Component component)
{
super(component);
}
@Override
public void doSomething()
{
super.doSomething();
this.doAnotherThing();
}
private void doAnotherThing()
{
System.out.println("功能B");
}
}
public class ConcreteDecorator2 extends Decorator
{
public ConcreteDecorator2(Component component)
{
super(component);
}
@Override
public void doSomething()
{
super.doSomething();
this.doAnotherThing();
}
private void doAnotherThing()
{
System.out.println("功能C");
}
}
使用测试:
public class Client
{
public static void main(String[] args)
{
Component component = new ConcreteComponent();
Component component1 = new ConcreteDecorator1(component);
component1.doSomething();
System.out.println("-----------");
Component component2 = new ConcreteDecorator2(component1);
component2.doSomething();
}
}
输出:
功能A
功能B
-----------
功能A
功能B
功能C
在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
举例:
public class Test {
// 将内容写到另一个文件
public void write() {
String string = "测试包装模式";
try {
FileWriter fw = new FileWriter("D:/copyfile.txt");
// 用到包装模式,扩展FileWriter的功能
BufferedWriter bW = new BufferedWriter(fw);
bW.write(string);
bW.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Test test = new Test();
test.write();
}
}
执行结果:
java装饰模式和继承的区别如下:
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。