Structural patterns 结构型模式
1.适配器模式(Adaptor)
目的:将某个类/接口转换为client期望的其他形式。适配器让类可以协同工作,否则就会因为不兼容的接口而无法工作。通过增加 一个接口,将已存在的子类封装起来,client 面向接口编程,从而隐藏了具体子类。
假设我们有一个MediaPlayer接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。
要想让AudioPlayer 播放其他格式的音频文件。需要一个适配器,这个适配器实现了MediaPayer接口,在这个适配器类里,用AdvancedMediaPlayer接口,实例化实现它的两个类,
public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType){
if(audioType.equalsIgnoreCase("vlc") ){
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
然后在正常实现MediaPlayer接口的实体类里,提供播放其他文件格式的支持,
1 public class AudioPlayer implements MediaPlayer {
2 MediaAdapter mediaAdapter;
3
4 @Override
5 public void play(String audioType, String fileName) {
6
7 //播放 mp3 音乐文件的内置支持
8 if(audioType.equalsIgnoreCase("mp3")){
9 System.out.println("Playing mp3 file. Name: "+ fileName);
10 }
11 //mediaAdapter 提供了播放其他文件格式的支持
12 else if(audioType.equalsIgnoreCase("vlc")
13 || audioType.equalsIgnoreCase("mp4")){
14 mediaAdapter = new MediaAdapter(audioType);
15 mediaAdapter.play(audioType, fileName);
16 }
17 else{
18 System.out.println("Invalid media. "+
19 audioType + " format not supported");
20 }
21 }
22 }
装饰器模式(Decorator)
装饰器模式是为了解决以下问题出现的一个设计模式:为对象增加不同侧面的 特性。 在这种设计模式下,我们对每一个特性构造子类,通过委派机制增加到对象 上。
装饰器 vs. 继承
• 装饰器在运行时组成特征;继承在编译时组成特征。
• 装饰器由多个协作对象组成;继承产生一个明确类型的对象。
• 可以混合和匹配多个装饰;多重继承在概念上是困难的。
外观模式(Facade Pattern)
隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
创建一个接口。
Shape.java
public interface Shape {
void draw();
}
创建实现接口的实体类。
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Rectangle::draw()");
}
}
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square::draw()");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Circle::draw()");
}
}
创建一个外观类。
ShapeMaker.java
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
private Shape square;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}
public void drawCircle(){
circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
public void drawSquare(){
square.draw();
}
}
使用该外观类画出各种类型的形状。
FacadePatternDemo.java
public class FacadePatternDemo {
public static void main(String[] args) {
ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle();
shapeMaker.drawRectangle();
shapeMaker.drawSquare();
}
}