设计模式——装饰模式
装饰模式
问题引入
现在有这样的两个类Draw和Color并且这两个类有一个相同的方法draw
Draw负责画画Color负责上色- 他们都使用
draw方法来画画或者上色
class Draw {
void draw() {
System.out.println("画画");
}
}
class Color {
void draw() {
System.out.println("上色");
}
}
现在我要在画画的时候同时上色,有哪些方法可以完成?
实现方法
方式一 实例化一个需要的对象
只需要在其中的一个类的方法中实例化另一个类,调用该类的方法即可
public class Test01 {
public static void main(String[] args) {
Color color = new Color();
// 可以实现同时画画和上色
color.draw();
}
}
class Draw {
void draw() {
System.out.println("画画");
}
}
class Color {
void draw() {
Draw draw = new Draw();
draw.draw();
System.out.println("上色");
}
}
这种方式的耦合度很高,需要更换就需要改代码
方式二 继承
只需要让其中的一个类继承另一个类,再调用父类的方法即可实现
public class Test01 {
public static void main(String[] args) {
Color color = new Color();
// 同时画画和上色
color.draw();
}
}
class Draw {
void draw() {
System.out.println("画画");
}
}
class Color extends Draw {
@Override
void draw() {
// 使用父类中的方法画画
super.draw();
System.out.println("上色");
}
}
这种方式的缺点是java只能单继承,如果需要继承其他的类就无法实现
这种方式的优点就是可以扩展JDK中的类
方式三 接口+构造器
- 将两个类中相同的方法放在接口中
- 让他们都实现这个接口
- 将这个接口作为构造器的参数
- 用的时候传入另一个对象即可
public class Test01 {
public static void main(String[] args) {
Color color = new Color(new Draw());
color.draw();
}
}
class Draw implements Work {
@Override
public void draw() {
System.out.println("画画");
}
}
class Color implements Work {
Work work;
public Color(Work work) {
this.work = work;
}
@Override
public void draw() {
work.draw();
System.out.println("上色");
}
}
interface Work {
void draw();
}
这种方式实现了解耦合,需要用哪个就通过构造器传哪个就行,不需要更改代码
方式四 成员变量+构造器
方式三虽然很不错,但是只在我们自己写的类中才能实现
如果要扩展jdk的类,我们不能更改源码,所以需要另一种方式
案例: 给BufferReader的read功能添加行号和字符统计的功能
public class Test02 {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader("E:\\aaa.txt")
);
MyBufferReader myBufferReader = new MyBufferReader(reader);
String s;
while ((s = myBufferReader.readerLine()) != null) {
System.out.println(s);
}
/* 运行结果:成功扩展
* 1 aaaaaaa 字符数7
* 2 bbbbbbb 字符数7
* 3 ccccccc 字符数7
* 4 ddddddd 字符数7
*/
}
}
class MyBufferReader {
private final BufferedReader reader;
private static int lineCount = 1;
public MyBufferReader(BufferedReader reader) {
this.reader = reader;
}
public String readerLine() throws IOException {
String s = reader.readLine();
if (s == null) {
return null;
}
return (lineCount++) + " " + s + " 字符数" + s.length();
}
}
我们扩展的对象就是被装饰对象
也可以使用继承的方式来实现
public class Test02 {
public static void main(String[] args) throws IOException {
MyBufferReader myBufferReader = new MyBufferReader(
new FileReader("E:\\aaa.txt")
);
String s;
while ((s = myBufferReader.readerLine()) != null) {
System.out.println(s);
}
}
}
class MyBufferReader extends BufferedReader {
private static int lineCount = 1;
public MyBufferReader(Reader in) {
super(in);
}
public String readerLine() throws IOException {
String s = super.readLine();
if (s == null) {
return null;
}
return (lineCount++) + " " + s + " 字符数" + s.length();
}
}

浙公网安备 33010602011771号