开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 22 天,点击查看活动详情
每日英语:
Concision in style,precision in thought,decision in life.
文体要简洁,思想要严谨,生活要果断。 -维克多·雨果
除了上一篇介绍的装饰者模式、模板方法模式、策略模式,还有很多其他常用的设计模式。在这里,我将介绍几种常见的设计模式,并提供相应的Java代码案例。
代理模式
代理模式(Proxy Pattern)为其他对象提供一种代理以控制对这个对象的访问。它是一种结构型设计模式,它可以为其他对象提供一个代理对象,以控制对原始对象的访问。以下是一个Java代码示例:
public interface Image {
void display();
}
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName) {
System.out.println("Loading " + 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是一个接口,它定义了一个显示图像的方法。RealImage是一个具体的图像实现类,它实现了Image接口,并定义了加载图像文件的方法。ProxyImage是一个代理类,它也实现了Image接口,并持有一个RealImage对象的引用。在ProxyImage的display方法中,如果RealImage对象尚未创建,则它将创建一个并显示它。
适配器模式
适配器模式(Adapter Pattern)将一个类的接口转换成客户端所期望的另一种接口,从而使得原本不兼容的接口可以协同工作。
以下是一个Java代码示例:
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) {
// do nothing
}
}
public class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// do nothing
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
}
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer player;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
player = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
player = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
player.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
player.playMp4(fileName);
}
}
}
public class AudioPlayer implements MediaPlayer {
private MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing MP3 file: " + fileName);
} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media type: " + audioType);
}
}
}
public class Client {
public static void main(String[] args) {
AudioPlayer player = new AudioPlayer();
player.play("mp3", "song.mp3");
player.play("vlc", "movie.vlc");
player.play("mp4", "video.mp4");
player.play("avi", "movie.avi");
}
}
在上面的代码中,MediaPlayer是一个接口,它定义了一个play()方法,用于播放媒体文件。AdvancedMediaPlayer是另一个接口,它定义了playVlc()和playMp4()方法,用于播放VLC和MP4格式的媒体文件。
VlcPlayer和Mp4Player是具体的媒体播放器实现类,它们实现了AdvancedMediaPlayer接口,并分别实现了播放VLC和MP4格式的媒体文件的方法。
MediaAdapter是一个适配器类,它实现了MediaPlayer接口,并持有一个AdvancedMediaPlayer实例。
原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保持性能的设计模式。通过复制已有对象的数据来创建新对象,而不是使用实例化过程。
以下是一个Java代码示例:
public abstract class Shape implements Cloneable {
private String id;
protected String type;
public String getId() {
return id;
}
public String getType() {
return type;
}
public void setId(String id) {
this.id = id;
}
public abstract void draw();
@Override
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
public class Circle extends Shape {
public Circle() {
type = "Circle";
}
@Override
public void draw() {
System.out.println("Drawing a circle.");
}
}
public class Square extends Shape {
public Square() {
type = "Square";
}
@Override
public void draw() {
System.out.println("Drawing a square.");
}
}
public class ShapeCache {
private static Map<String, Shape> shapeMap = new HashMap<>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
public static void loadCache() {
Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(), circle);
Square square = new Square();
square.setId("2");
shapeMap.put(square.getId(), square);
}
}
public class Client {
public static void main(String[] args) {
ShapeCache.loadCache();
Shape clonedShape1 = ShapeCache.getShape("1");
System.out.println("Shape: " + clonedShape1.getType());
Shape clonedShape2 = ShapeCache.getShape("2");
System.out.println("Shape: " + clonedShape2.getType());
}
}
总结
本篇主要讲了一下代理模式、适配器模式、原型模式这三种,并给了对应的代码示例,有兴趣的小伙伴可以拿来跑跑,学习学习。