设计模式
1. 适配器模式 (Adapter Pattern)
将一个类的接口转换成客户希望的另一个接口,使原本不兼容的类可以一起工作。
// 目标接口
public interface MediaPlayer {
void play(String audioType, String fileName);
}
// 被适配者
public class Mp3Player {
public void playMp3(String fileName) {
System.out.println("Playing MP3 file: " + fileName);
}
}
public class Mp4Player {
public void playMp4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
}
// 适配器
public class MediaAdapter implements MediaPlayer {
Mp4Player mp4Player;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("mp4")) {
mp4Player = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp4")) {
mp4Player.playMp4(fileName);
}
}
}
// 适配器实现
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
// 内置支持MP3播放
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing MP3 file: " + fileName);
}
// 对于其他格式,使用适配器
else if (audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media type: " + audioType);
}
}
}
// 使用示例
public class AdapterDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "song.mp3");
audioPlayer.play("mp4", "video.mp4");
audioPlayer.play("avi", "movie.avi");
}
}
2. 模板方法模式 (Template Method Pattern)
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。
// 抽象模板类
public abstract class Game {
// 模板方法,定义游戏流程
public final void play() {
// 初始化游戏
initialize();
// 开始游戏
startPlay();
// 进行游戏
endPlay();
}
// 抽象方法,由子类实现
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
// 钩子方法,子类可以选择性重写
void endPlay() {
System.out.println("Game Finished!");
}
}
// 具体实现类
public class Cricket extends Game {
@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}
}
public class Football extends Game {
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
}
// 使用示例
public class TemplatePatternDemo {
public static void main(String[] args) {
Game game = new Cricket();
game.play();
System.out.println();
game = new Football();
game.play();
}
}
3. 命令模式 (Command Pattern)
将请求封装成对象,从而使你可以用不同的请求对客户进行参数化。
// 命令接口
public interface Order {
void execute();
}
// 接收者
public class Stock {
private String name = "ABC";
private int quantity = 10;
public void buy() {
System.out.println("Stock [ Name: " + name + ", Quantity: " + quantity + " ] bought");
}
public void sell() {
System.out.println("Stock [ Name: " + name + ", Quantity: " + quantity + " ] sold");
}
}
// 具体命令
public class BuyStock implements Order {
private Stock abcStock;
public BuyStock(Stock abcStock) {
this.abcStock = abcStock;
}
public void execute() {
abcStock.buy();
}
}
public class SellStock implements Order {
private Stock abcStock;
public SellStock(Stock abcStock) {
this.abcStock = abcStock;
}
public void execute() {
abcStock.sell();
}
}
// 调用者
public class Broker {
private List<Order> orderList = new ArrayList<Order>();
public void takeOrder(Order order) {
orderList.add(order);
}
public void placeOrders() {
for (Order order : orderList) {
order.execute();
}
orderList.clear();
}
}
// 使用示例
public class CommandPatternDemo {
public static void main(String[] args) {
Stock abcStock = new Stock();
BuyStock buyStockOrder = new BuyStock(abcStock);
SellStock sellStockOrder = new SellStock(abcStock);
Broker broker = new Broker();
broker.takeOrder(buyStockOrder);
broker.takeOrder(sellStockOrder);
broker.placeOrders();
}
}
4. 状态模式 (State Pattern)
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
// 状态接口
public interface State {
void doAction(Context context);
}
// 上下文类
public class Context {
private State state;
public Context() {
this.state = null;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
// 具体状态实现
public 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";
}
}
public 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";
}
}
// 使用示例
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.doAction(context);
System.out.println(context.getState().toString());
StopState stopState = new StopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}
5. 建造者模式 (Builder Pattern)
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
// 产品类
public class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item) {
items.add(item);
}
public float getCost() {
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems() {
for (Item item : items) {
System.out.print("Item : " + item.name());
System.out.print(", Packing : " + item.packing().pack());
System.out.println(", Price : " + item.price());
}
}
}
// 接口定义
public interface Item {
String name();
Packing packing();
float price();
}
public interface Packing {
String pack();
}
// 包装实现
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
// 具体项目
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
// 建造者
public class MealBuilder {
public Meal prepareVegMeal() {
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal() {
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
// 使用示例
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " + vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " + nonVegMeal.getCost());
}
}
6. 代理模式 (Proxy Pattern)
为其他对象提供一种代理以控制对这个对象的访问。
// 接口
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();
}
}
// 使用示例
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
// 图像将从磁盘加载
image.display();
System.out.println("");
// 图像不需要从磁盘加载
image.display();
}
}
这些设计模式在不同的场景中发挥着重要作用:
- 适配器模式 - 用于系统集成和兼容性处理
- 模板方法模式 - 用于定义算法骨架,让子类实现具体步骤
- 命令模式 - 用于实现撤销操作、队列请求、日志记录等
- 状态模式 - 用于处理对象的状态转换和行为变化
- 建造者模式 - 用于创建复杂对象,提高代码可读性和维护性
- 代理模式 - 用于延迟加载、访问控制、日志记录等

浙公网安备 33010602011771号