1. 请解释建造者模式(Builder Pattern)及其应用场景。
答案:
建造者模式用于创建一个复杂的对象,同时允许用户只通过指定复杂对象的类型和内容就能构建它们,隐藏了复杂的构建逻辑。
示例:
public class Car {
private String engine;
private String wheels;
private String color;
public Car(String engine, String wheels, String color) {
this.engine = engine;
this.wheels = wheels;
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"engine='" + engine + '\'' +
", wheels='" + wheels + '\'' +
", color='" + color + '\'' +
'}';
}
}
public class CarBuilder {
private String engine;
private String wheels;
private String color;
public CarBuilder setEngine(String engine) {
this.engine = engine;
return this;
}
public CarBuilder setWheels(String wheels) {
this.wheels = wheels;
return this;
}
public CarBuilder setColor(String color) {
this.color = color;
return this;
}
public Car build() {
return new Car(engine, wheels, color);
}
}
// 使用
Car car = new CarBuilder()
.setEngine("V8")
.setWheels("Alloy")
.setColor("Red")
.build();
System.out.println(car);
应用场景:
- 当对象的构建过程复杂,且需要逐步设置多个属性时。
- 当对象的构建逻辑可能变化时,使用建造者模式可以灵活调整。
2. 请解释适配器模式(Adapter Pattern)及其应用场景。
答案:
适配器模式用于将一个类的接口转换为客户期望的另一个接口,从而使原本不兼容的接口能够一起工作。
示例:
public interface MediaPlayer {
void play(String audioType, String fileName);
}
public interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
public class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing VLC file: " + fileName);
}
@Override
public void playMp4(String fileName) {
throw new UnsupportedOperationException();
}
}
public class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
throw new UnsupportedOperationException();
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
}
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMediaPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMediaPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMediaPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMediaPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMediaPlayer.playMp4(fileName);
}
}
}
// 使用
MediaPlayer player = new MediaAdapter("vlc");
player.play("vlc", "sample.vlc");
应用场景:
- 当需要将第三方库或遗留代码集成到现有系统中时。
- 当需要扩展系统的功能,但不想修改现有代码时。
3. 请解释代理模式(Proxy Pattern)及其应用场景。
答案:
代理模式提供了一种代理对象,该对象内部含有对真实对象的引用,通过代理对象来间接访问真实对象,从而在不改变真实对象代码的情况下,添加一层间接层来控制对真实对象的访问。
示例:
public interface Image {
void display();
}
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(fileName);
}
private void loadFromDisk(String fileName) {
System.out.println("Loading " + fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
}
public class ProxyImage implements Image {
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName) {
this.fileName = fileName;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(fileName);
}
realImage.display();
}
}
// 使用
Image image = new ProxyImage("test.jpg");
image.display();
应用场景:
- 当需要延迟加载资源时(如图片)。
- 当需要控制对对象的访问时(如权限检查)。
4. 请解释模板方法模式(Template Method Pattern)及其应用场景。
答案:
模板方法模式定义了一个操作中的算法骨架,将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤。
示例:
public abstract class Game {
protected abstract void initialize();
protected abstract void startPlay();
protected abstract void endPlay();
public final void play() {
initialize();
startPlay();
endPlay();
}
}
public class Cricket extends Game {
@Override
protected void initialize() {
System.out.println("Cricket game initialization");
}
@Override
protected void startPlay() {
System.out.println("Cricket game started");
}
@Override
protected void endPlay() {
System.out.println("Cricket game finished");
}
}
public class Football extends Game {
@Override
protected void initialize() {
System.out.println("Football game initialization");
}
@Override
protected void startPlay() {
System.out.println("Football game started");
}
@Override
protected void endPlay() {
System.out.println("Football game finished");
}
}
// 使用
Game game = new Cricket();
game.play();
应用场景:
- 当多个子类共享相同的算法结构,但某些步骤需要根据子类不同而变化时。
- 当需要定义算法的骨架,但允许子类灵活实现某些步骤时。
5. 请解释门面模式(Facade Pattern)及其应用场景。
答案:
门面模式提供了一个统一的高层接口,用于访问子系统中的一群接口。它定义了一个高层接口,让子系统更容易使用。
示例:
public class SubSystemA {
public void methodA() {
System.out.println("SubSystemA methodA");
}
}
public class SubSystemB {
public void methodB() {
System.out.println("SubSystemB methodB");
}
}
public class SubSystemC {
public void methodC() {
System.out.println("SubSystemC methodC");
}
}
public class Facade {
private SubSystemA a;
private SubSystemB b;
private SubSystemC c;
public Facade() {
a = new SubSystemA();
b = new SubSystemB();
c = new SubSystemC();
}
public void operation() {
a.methodA();
b.methodB();
c.methodC();
}
}
// 使用
Facade facade = new Facade();
facade.operation();
应用场景:
- 当需要简化一个复杂子系统的使用时。
- 当需要提供一个统一的接口,隐藏子系统的复杂性时。