部分设计模式(java语言版本)
1. 单例模式 (Singleton Pattern)
原理: 确保一个类只有一个实例,并提供一个全局访问点。
public class Singleton {
private static Singleton instance;
// 私有构造函数,防止外部实例化
private Singleton() {}
// 提供全局访问点
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
解释: Singleton
类只有一个实例,通过 getInstance()
方法获取。如果实例未创建,则会创建并返回,否则返回已有的实例。
2. 工厂模式 (Factory Pattern)
原理: 定义一个创建对象的接口,但让子类决定实例化哪个类。
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
System.out.println("Drawing a Circle");
}
}
class Rectangle implements Shape {
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
class ShapeFactory {
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}
解释: ShapeFactory
类根据传入的形状类型,返回相应的 Shape
实例。这样可以将对象创建的细节封装在工厂中,客户端不需要知道具体的创建过程。
3. 策略模式 (Strategy Pattern)
原理: 定义一系列算法,将每一个算法封装起来,并使它们可以互换。
interface Strategy {
int doOperation(int num1, int num2);
}
class AddOperation implements Strategy {
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
class SubtractOperation implements Strategy {
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
解释: Context
类根据传入的 Strategy
实例,执行对应的算法操作。这种设计模式可以让算法在运行时更灵活地替换。
4. 观察者模式 (Observer Pattern)
原理: 定义对象间的一对多依赖,一个对象改变状态时,所有依赖的对象都会收到通知并自动更新。
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class Subject {
private List<Observer> observers = new ArrayList<>();
private String message;
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(message);
}
}
public void setMessage(String message) {
this.message = message;
notifyObservers();
}
}
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}
解释: Subject
类维护一个观察者列表,当状态变化时,通过调用 notifyObservers()
方法通知所有观察者。ConcreteObserver
是具体的观察者实现,它会根据收到的消息进行响应。
5. 装饰器模式 (Decorator Pattern)
原理: 动态地给对象添加新的职责,通过组合而不是继承来扩展功能。
interface Car {
void assemble();
}
class BasicCar implements Car {
public void assemble() {
System.out.println("Assembling a Basic Car");
}
}
class CarDecorator implements Car {
protected Car car;
public CarDecorator(Car car) {
this.car = car;
}
public void assemble() {
this.car.assemble();
}
}
class SportsCar extends CarDecorator {
public SportsCar(Car car) {
super(car);
}
public void assemble() {
super.assemble();
System.out.println("Adding features of a Sports Car");
}
}
class LuxuryCar extends CarDecorator {
public LuxuryCar(Car car) {
super(car);
}
public void assemble() {
super.assemble();
System.out.println("Adding features of a Luxury Car");
}
}
解释: 装饰器模式允许通过组合现有对象来动态扩展功能,而不是通过继承。CarDecorator
类是一个基础装饰器类,而 SportsCar
和 LuxuryCar
则是具体的装饰器,增加了不同的功能。
6. 代理模式 (Proxy Pattern)
原理: 为其他对象提供一种代理,以控制对这个对象的访问。
interface Image {
void display();
}
class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading " + fileName);
}
public void display() {
System.out.println("Displaying " + fileName);
}
}
class ProxyImage implements Image {
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName) {
this.fileName = fileName;
}
public void display() {
if (realImage == null) {
realImage = new RealImage(fileName);
}
realImage.display();
}
}
解释: ProxyImage
类通过代理模式延迟加载 RealImage
,只有在真正需要显示时才创建 RealImage
实例,从而节省内存或提高性能。
7. 建造者模式 (Builder Pattern)
原理: 将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。
class Computer {
// 必选参数
private String HDD;
private String RAM;
// 可选参数
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
private Computer(ComputerBuilder builder) {
this.HDD = builder.HDD;
this.RAM = builder.RAM;
this.isGraphicsCardEnabled = builder.isGraphicsCardEnabled;
this.isBluetoothEnabled = builder.isBluetoothEnabled;
}
public static class ComputerBuilder {
private String HDD;
private String RAM;
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public ComputerBuilder(String HDD, String RAM) {
this.HDD = HDD;
this.RAM = RAM;
}
public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
this.isGraphicsCardEnabled = isGraphicsCardEnabled;
return this;
}
public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
this.isBluetoothEnabled = isBluetoothEnabled;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
解释: Builder
模式通过 ComputerBuilder
类使得 Computer
对象的构建过程更灵活。可以根据需要选择性地设置可选参数,而不需要创建过多的构造函数。
8. 原型模式 (Prototype Pattern)
原理: 使用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。
import java.util.HashMap;
import java.util.Map;
abstract class Shape implements Cloneable {
private String id;
protected String type;
abstract void draw();
public String getType() {
return type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
class Circle extends Shape {
public Circle() {
type = "Circle";
}
public void draw() {
System.out.println("Drawing a Circle");
}
}
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);
Rectangle rectangle = new Rectangle();
rectangle.setId("2");
shapeMap.put(rectangle.getId(), rectangle);
}
}
解释: Shape
类实现了 Cloneable
接口,通过 clone()
方法实现对象的复制。ShapeCache
类预加载了一些对象,通过克隆这些对象来创建新实例。
9. 适配器模式 (Adapter Pattern)
原理: 将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而无法一起工作的类可以协同工作。
interface MediaPlayer {
void play(String audioType, String fileName);
}
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
class VlcPlayer implements AdvancedMediaPlayer {
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
public void playMp4(String fileName) {
// 什么也不做
}
}
class Mp4Player implements AdvancedMediaPlayer {
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
public void playVlc(String fileName) {
// 什么也不做
}
}
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();
}
}
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
public void play(String audioType, String fileName) {
// 内置支持mp3格式音乐播放
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file. Name: " + fileName);
}
// 使用适配器支持其他格式
else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media. " + audioType + " format not supported");
}
}
}
解释: AudioPlayer
类本身只支持 mp3
格式,但通过使用 MediaAdapter
类,它能够播放 vlc
和 mp4
格式的文件,适配器将不兼容的接口转化为兼容的接口。
10. 享元模式 (Flyweight Pattern)
原理: 运用共享技术有效地支持大量细粒度对象的复用。
import java.util.HashMap;
interface Shape {
void draw();
}
class Circle implements Shape {
private String color;
private int x;
private int y;
private int radius;
public Circle(String color) {
this.color = color;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setRadius(int radius) {
this.radius = radius;
}
public void draw() {
System.out.println("Drawing Circle [Color: " + color + ", x: " + x + ", y: " + y + ", radius: " + radius + "]");
}
}
class ShapeFactory {
private static final HashMap<String, Shape> circleMap = new HashMap<>();
public static Shape getCircle(String color) {
Circle circle = (Circle) circleMap.get(color);
if (circle == null) {
circle = new Circle(color);
circleMap.put(color, circle);
System.out.println("Creating circle of color : " + color);
}
return circle;
}
}
解释: ShapeFactory
类通过共享现有的 Circle
实例来避免创建过多的对象,从而节省内存。这是享元模式的核心思想,即通过共享对象减少内存使用。
这些设计模式展示了如何在不同场景下解决常见的设计问题,使代码更具扩展性、可维护性和重用性。
继续介绍一些常见的设计模式及其在Java中的实现。
11. 责任链模式 (Chain of Responsibility Pattern)
原理: 为请求创建一系列处理对象,每个处理对象决定是否处理请求或将请求传递到链上的下一个对象。
abstract class Logger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
// 责任链中的下一个元素
protected Logger nextLogger;
public void setNextLogger(Logger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message) {
if (this.level <= level) {
write(message);
}
if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
class ConsoleLogger extends Logger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
class ErrorLogger extends Logger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}
class FileLogger extends Logger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
解释: Logger
类定义了处理请求的接口,并包含了对下一个处理对象的引用。不同类型的日志记录器(如 ConsoleLogger
、ErrorLogger
、FileLogger
)决定如何处理请求或将其传递给下一个处理器。客户端可以通过创建责任链来灵活配置请求的处理流程。
12. 命令模式 (Command Pattern)
原理: 将请求封装成对象,从而允许参数化不同的请求、队列请求或记录请求日志。
interface Command {
void execute();
}
class Light {
public void on() {
System.out.println("Light is ON");
}
public void off() {
System.out.println("Light is OFF");
}
}
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
public void execute() {
light.off();
}
}
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
解释: Command
接口定义了一个执行操作的 execute()
方法。LightOnCommand
和 LightOffCommand
实现了 Command
接口,通过 RemoteControl
类将命令与操作解耦,客户可以在运行时动态地指定命令。
13. 迭代器模式 (Iterator Pattern)
原理: 提供一种方法顺序访问一个集合对象中的各个元素,而不暴露其内部的表示。
interface Iterator {
boolean hasNext();
Object next();
}
interface Container {
Iterator getIterator();
}
class NameRepository implements Container {
public String names[] = {"Robert", "John", "Julie", "Lora"};
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
public boolean hasNext() {
if (index < names.length) {
return true;
}
return false;
}
public Object next() {
if (this.hasNext()) {
return names[index++];
}
return null;
}
}
}
解释: NameRepository
类实现了 Container
接口,提供了获取 Iterator
的方法。NameIterator
是一个内部类,用于遍历 names
数组的元素。通过这种方式,客户端可以遍历集合,而不需要知道集合的内部实现。
14. 模板方法模式 (Template Method Pattern)
原理: 定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
// 模板方法
public final void play() {
// 初始化游戏
initialize();
// 开始游戏
startPlay();
// 结束游戏
endPlay();
}
}
class Cricket extends Game {
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
void endPlay() {
System.out.println("Cricket Game Finished!");
}
}
class Football extends Game {
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
void endPlay() {
System.out.println("Football Game Finished!");
}
}
解释: Game
类定义了游戏的算法骨架,并包含一个不可修改的模板方法 play()
。子类 Cricket
和 Football
实现了算法的具体步骤。通过模板方法,算法的整体结构得以保持一致,而各步骤的具体实现可以由子类自行定义。
15. 状态模式 (State Pattern)
原理: 允许对象在内部状态发生改变时改变其行为,对象看起来似乎修改了它的类。
interface State {
void doAction(Context context);
}
class StartState implements State {
public void doAction(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}
public String toString() {
return "Start State";
}
}
class StopState implements State {
public void doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
public String toString() {
return "Stop State";
}
}
class Context {
private State state;
public Context() {
state = null;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
解释: Context
类维护一个 State
对象,通过 setState()
方法可以改变当前状态。StartState
和 StopState
类实现了 State
接口,通过不同的状态实现对象行为的动态变化。
16. 中介者模式 (Mediator Pattern)
原理: 定义一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使它们可以松散耦合,且可以独立地改变它们之间的交互。
import java.util.ArrayList;
import java.util.List;
class ChatRoom {
public static void showMessage(User user, String message) {
System.out.println(user.getName() + ": " + message);
}
}
class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void sendMessage(String message) {
ChatRoom.showMessage(this, message);
}
}
解释: ChatRoom
类作为中介者,负责用户之间的消息传递。User
类通过中介者发送消息,而不是直接与其他用户进行交互,这样的设计减少了对象之间的依赖。
17. 备忘录模式 (Memento Pattern)
原理: 在不破坏封装性的前提下,捕获对象的内部状态,并在该对象之外保存这个状态,以便日后恢复对象到之前的状态。
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
public Memento saveStateToMemento() {
return new Memento(state);
}
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
class Caretaker {
private List<Memento> mementoList = new ArrayList<>();
public void add(Memento state) {
mementoList.add(state);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
解释: Originator
类负责创建并恢复状态到 Memento
对象中。Caretaker
类负责保存 `M