这是一份设计模式学习指南,包含多个作业和真题练习,帮助你掌握各种设计模式的应用。
小王为某管理信息系统的用户管理模块设计了如图所示接口。
- 请你从面向对象设计原则的角度详细分析小王的设计存在什么问题?
- 请你采用面向对象方法帮小王重新设计,使得新设计能够符合面向对象设计原则。简要说明你的设计思想,画出UML类图。
该设计违背了接口隔离原则和单一职责原则。
该接口进行重构设计,将其中的一些方法封装在两个不同的接口中,确保每一个接口使用起来都较为方便。如下面两种重构方案皆可。
客户请小王编写一个从键盘读入字符并输出到打印机的程序。小王使用结构化的设计方法,编写了如下代码。该程序包含3个子程序,Copy子程序从ReadKeyboard子程序中获取字符,并把字符传递给WritePrinter子程序。几个月后,客户说有时希望Copy程序能从纸带读入机中读入字符。并且,在未来可能还会从其它种类的输入设备中读入字符,也可能输出到其它种类的输出设备。小王希望他写出的代码既能满足上述要求,又不用每次都改写Copy的实现。
请采用面向对象方法通过恰当的设计模式对小王的代码进行重构。请写出你所选择的设计模式,画出类图,并给出核心代码。
class Reader {
public:
virtual char Read() = 0;
};
class Writer {
public:
virtual void Write(char c) = 0;
};
class KeyboardReader : public Reader {
public:
char Read() override {
char c;
cin >> c;
return c;
}
};
class PaperReader : public Reader {
public:
char Read() override {
// 从纸带读入机读取字符
return ' ';
}
};
class PrintWriter : public Writer {
public:
void Write(char c) override {
cout << c;
}
};
KeyboardReader DefaultReader;
PrintWriter DefaultWriter;
void Copy(Reader &reader = DefaultReader, Writer &writer = DefaultWriter) {
char c;
while ((c = reader.Read()) != EOF) {
writer.Write(c);
}
}一个开宝箱游戏的基本描述为:游戏中有多种类型的人物(Role),如战士(Solider)、魔法师(Mage)等,主角的类型只能选择其中一种,且游戏中不再更改。游戏中还有各种宝箱(Box),如装有不同数目金钱的宝箱、装有毒物的宝箱等。当任一种类型的主角打开装有金钱的宝箱时,宝箱中的金钱会增加给主角,同时宝箱的金钱数目变成0;当战士打开装有毒物的宝箱时,战士的生命值(HP)会减少10%,但金钱(Money)会增加40%;当魔法师打开装有毒物的宝箱时,魔法师的HP会减少20%,但Money会增加20%。
请根据上述描述,给出相应类的设计并完整实现,要求你的设计应具有良好的扩展性,如增加新角色类型及箱子种类时,不需要修改已有的设计及实现。
class Role {
protected:
int hp;
int money;
public:
virtual void PoisonHurt() = 0;
virtual void AddMoney(int m) { money += m; }
int GetMoney() { return money; }
void SetMoney(int m) { money = m; }
};
class Soldier : public Role {
public:
void PoisonHurt() override {
hp *= 0.9;
money *= 1.4;
}
};
class Mage : public Role {
public:
void PoisonHurt() override {
hp *= 0.8;
money *= 1.2;
}
};
class Box {
public:
virtual ~Box() {}
virtual void BeOpened(Role &role) = 0;
};
class MoneyBox : public Box {
private:
int boxMoney;
public:
MoneyBox(int m) : boxMoney(m) {}
void BeOpened(Role &role) override {
role.SetMoney(role.GetMoney() + boxMoney);
boxMoney = 0;
}
int GetBoxMoney() { return boxMoney; }
};
class PoisonBox : public Box {
public:
void BeOpened(Role &role) override {
role.PoisonHurt();
}
};给出适当的类设计和相应的代码: 有一个只能放进不能取出的盒子, 最多可放8个水果, 不一定一天放入。水果只是苹果和桔子两种, 它们放入盒子前的原始重量分别为50和30, 放入盒子后, 由于丢失水分, 它们的重量减轻, 苹果和桔子每天分别减轻4和3, 直到达到各自原始重量的3/5后, 不再减轻重量。
盒子的功能有:
- 输出盒子中苹果的数量
- 输出盒子中桔子的数量
- 输出一天来盒子中水果减轻的总重量
- 输出当前水果的总重量
class Fruit {
protected:
int mMaxWeight;
int mMinWeight;
int mLoseWeight;
int mWeight;
public:
Fruit(int mMax = 0, int mMin = 0, int mLose = 0, int mW = 0)
: mMaxWeight(mMax), mMinWeight(mMin), mLoseWeight(mLose), mWeight(mW) {}
virtual int ReduceWeight();
virtual int Weight() const;
virtual Fruit* Clone() = 0;
};
int Fruit::ReduceWeight() {
int newWeight = mWeight - mLoseWeight;
if (newWeight < mMinWeight)
newWeight = mMinWeight;
int reduce = mWeight - newWeight;
mWeight = newWeight;
return reduce;
}
int Fruit::Weight() const {
return mWeight;
}
class Apple : public Fruit {
public:
Apple() : Fruit(50, 50 * 3 / 5, 4, 50) {}
Fruit* Clone() override {
return new Apple(*this);
}
};
class Orange : public Fruit {
public:
Orange() : Fruit(30, 30 * 3 / 5, 3, 30) {}
Fruit* Clone() override {
return new Orange(*this);
}
};
class Box {
private:
Fruit* fruit[8];
int count;
public:
Box() : count(0) {
for (int i = 0; i < 8; i++)
fruit[i] = nullptr;
}
~Box() {
for (int i = 0; i < 8; i++)
delete fruit[i];
}
void AddFruit(Fruit &one) {
if (count < 8) {
fruit[count++] = one.Clone();
}
}
int ApplesNum() const {
int num = 0;
for (int i = 0; i < 8; i++) {
Apple* p = dynamic_cast<Apple*>(fruit[i]);
if (p)
num++;
}
return num;
}
int OrangesNum() const {
int num = 0;
for (int i = 0; i < 8; i++) {
Orange* p = dynamic_cast<Orange*>(fruit[i]);
if (p)
num++;
}
return num;
}
int PassOneDay() {
int totalReduce = 0;
for (int i = 0; i < 8; i++) {
if (fruit[i])
totalReduce += fruit[i]->ReduceWeight();
}
return totalReduce;
}
int TotalWeight() const {
int total = 0;
for (int i = 0; i < 8; i++) {
if (fruit[i])
total += fruit[i]->Weight();
}
return total;
}
void Show() {
cout << "苹果数量: " << ApplesNum() << endl;
cout << "桔子数量: " << OrangesNum() << endl;
cout << "当前总重量: " << TotalWeight() << endl;
}
};
int main() {
Box aBox;
Apple a1, a2, a3;
Orange o1, o2;
cout << "初始状态:" << endl;
aBox.Show();
aBox.AddFruit(a1);
cout << "\n添加一个苹果后:" << endl;
aBox.Show();
aBox.AddFruit(a2);
cout << "\n添加第二个苹果后:" << endl;
aBox.Show();
aBox.AddFruit(o1);
aBox.AddFruit(o2);
cout << "\n添加两个桔子后:" << endl;
aBox.Show();
int reduce = aBox.PassOneDay();
cout << "\n一天后:" << endl;
cout << "总减轻重量: " << reduce << endl;
aBox.Show();
return 0;
}小王正在编写一个简单的计算器程序,要求输入两个整数和运算符号(加、减、乘、除),输出计算结果。小王用面向过程方法编写了下面的代码。请采用面向对象方法通过恰当的设计模式对小王的代码进行重构。请写出你所选择的设计模式,画出类图,并给出核心代码。
abstract class Operation {
private int numberA;
private int numberB;
public abstract double getResult();
public int getNumberA() {
return numberA;
}
public void setNumberA(int numberA) {
this.numberA = numberA;
}
public int getNumberB() {
return numberB;
}
public void setNumberB(int numberB) {
this.numberB = numberB;
}
}
class AddOperation extends Operation {
@Override
public double getResult() {
return numberA + numberB;
}
}
class SubOperation extends Operation {
@Override
public double getResult() {
return numberA - numberB;
}
}
class MulOperation extends Operation {
@Override
public double getResult() {
return numberA * numberB;
}
}
class DivOperation extends Operation {
@Override
public double getResult() {
return numberA / (double) numberB;
}
}
class Calculator {
public static Operation createOperation(char operator) {
Operation op = null;
switch (operator) {
case '+':
op = new AddOperation();
break;
case '-':
op = new SubOperation();
break;
case '*':
op = new MulOperation();
break;
case '/':
op = new DivOperation();
break;
default:
System.out.println("非法操作符");
}
return op;
}
}
public class Client {
public static void main(String[] args) {
double result;
Operation op1 = Calculator.createOperation('+');
op1.setNumberA(5);
op1.setNumberB(10);
result = op1.getResult();
System.out.println(result);
}
}请为一校服制造厂编写一个校服生产子系统。该工厂可为多家学校生产校服,包括秋季校服和夏季校服。一套秋季校服含一件长袖上衣和一条秋季长裤,一套夏季校服含一件短袖衬衣、一件短袖T恤、一条夏季长裤和一条短裤。不同学校校服款式不同。
请设计一个子系统为三所学校(一中、二中、三中)分别生产秋季校服和夏季校服(均码)。例如,当用户输入"一中+夏季"时,系统就会生产出一套一中夏季校服;当用户输入"一中+秋季"时,系统生产出一套一中秋季校服。
请写出你所选择的设计模式,画出类图,并给出核心代码。
interface AbstractFactory {
public abstract SummerCloth createSummerCloth();
public abstract FallCloth createFallCloth();
}
class FactoryFirst implements AbstractFactory {
@Override
public SummerCloth createSummerCloth() {
return new SummerClothFirst();
}
@Override
public FallCloth createFallCloth() {
return new FallClothFirst();
}
}
class FactorySecond implements AbstractFactory {
@Override
public SummerCloth createSummerCloth() {
return new SummerClothSecond();
}
@Override
public FallCloth createFallCloth() {
return new FallClothSecond();
}
}
class FactoryThird implements AbstractFactory {
@Override
public SummerCloth createSummerCloth() {
return new SummerClothThird();
}
@Override
public FallCloth createFallCloth() {
return new FallClothThird();
}
}
interface SummerCloth {
public abstract void display();
}
class SummerClothFirst implements SummerCloth {
@Override
public void display() {
System.out.println("一中夏季校服");
}
}
class SummerClothSecond implements SummerCloth {
@Override
public void display() {
System.out.println("二中夏季校服");
}
}
class SummerClothThird implements SummerCloth {
@Override
public void display() {
System.out.println("三中夏季校服");
}
}
interface FallCloth {
public abstract void display();
}
class FallClothFirst implements FallCloth {
@Override
public void display() {
System.out.println("一中秋季校服");
}
}
class FallClothSecond implements FallCloth {
@Override
public void display() {
System.out.println("二中秋季校服");
}
}
class FallClothThird implements FallCloth {
@Override
public void display() {
System.out.println("三中秋季校服");
}
}
public class Client {
public static void main(String[] args) {
AbstractFactory f1, f2, f3;
f1 = new FactoryFirst();
f2 = new FactorySecond();
f3 = new FactoryThird();
SummerCloth c1, c2;
FallCloth c3;
c1 = f1.createSummerCloth();
c1.display();
c2 = f2.createSummerCloth();
c2.display();
c3 = f3.createFallCloth();
c3.display();
}
}小王正在设计一个导出数据的应用框架。客户要求:导出数据可能存储成不同的文件格式,例如:文本格式、数据库备份形式、Excel格式、Xml格式等等,并且,不管什么格式,导出数据文件都分成三个部分,分别是文件头、文件体和文件尾。
在文件头部分,需要描述如下信息:分公司或门市点编号、导出数据的日期,对于文本格式,中间用逗号分隔。
在文件体部分,需要描述如下信息:表名称、然后分条描述数据,对于文本格式,表名称单独占一行,数据描述一行算一条数据,字段间用逗号分隔。
在文件尾部分,需要描述如下信息:输出人。
请写出你所选择的设计模式,画出类图,并给出核心代码。
class File {
private String head;
private String body;
private String tail;
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTail() {
return tail;
}
public void setTail(String tail) {
this.tail = tail;
}
}
abstract class Builder {
protected File file = new File();
public File getFile() {
return file;
}
public abstract void buildHead();
public abstract void buildBody();
public abstract void buildTail();
}
class XmlBuilder extends Builder {
@Override
public void buildHead() {
file.setHead("xml文件头");
}
@Override
public void buildBody() {
file.setBody("xml文件体");
}
@Override
public void buildTail() {
file.setTail("xml文件尾");
}
}
class TextBuilder extends Builder {
@Override
public void buildHead() {
file.setHead("文本文件头");
}
@Override
public void buildBody() {
file.setBody("文本文件体");
}
@Override
public void buildTail() {
file.setTail("文本文件尾");
}
}
class DBBuilder extends Builder {
@Override
public void buildHead() {
file.setHead("数据库备份文件头");
}
@Override
public void buildBody() {
file.setBody("数据库备份文件体");
}
@Override
public void buildTail() {
file.setTail("数据库备份文件尾");
}
}
class ExcelBuilder extends Builder {
@Override
public void buildHead() {
file.setHead("Excel文件头");
}
@Override
public void buildBody() {
file.setBody("Excel文件体");
}
@Override
public void buildTail() {
file.setTail("Excel文件尾");
}
}
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public File construct() {
builder.buildHead();
builder.buildBody();
builder.buildTail();
return builder.getFile();
}
}
public class Client {
public static void main(String[] args) {
Director director = new Director(new XmlBuilder());
File file = director.construct();
System.out.println("xml格式组成:");
System.out.println(file.getHead());
System.out.println(file.getBody());
System.out.println(file.getTail());
}
}在下面的TicketMaker类(见下表)中,每次调用getNextTicketNumber方法都会返回1000,1001,1002…的数列。我们可以用它生成票的编号或是其他序列号。在现在该类的实现方式下,我们可以生成多个该类的实例。
请写出你所选择的设计模式,画出类图,并给出核心代码。
public class TicketMaker {
private static volatile TicketMaker instance;
private int ticketNumber = 1000;
private TicketMaker() {}
public static TicketMaker getInstance() {
if (instance == null) {
synchronized (TicketMaker.class) {
if (instance == null) {
instance = new TicketMaker();
}
}
}
return instance;
}
public synchronized int getNextTicketNumber() {
return ticketNumber++;
}
}请设计一个数据库连接池,要求最多只能创建3个连接实例。
import java.util.Random;
public class DBConnections {
private static DBConnections[] connections = {
new DBConnections(),
new DBConnections(),
new DBConnections()
};
private DBConnections() {}
public static DBConnections getInstance() {
return connections[random()];
}
public static int random() {
Random random = new Random();
int value = Math.abs(random.nextInt());
value %= 3;
return value;
}
public void ConnectionInfo() {
// 连接信息
}
public static void main(String[] args) {
DBConnections db1, db2, db3;
db1 = DBConnections.getInstance();
db2 = DBConnections.getInstance();
db3 = DBConnections.getInstance();
System.out.println(db1 == db2);
System.out.println(db1 == db3);
}
}请根据下面的对象适配器类图画出与之相对应的类适配器类图。
开发一个计算机操作系统的线程调度程序,要求实现时间片调度和抢占调度这2种调度算法,支持Windows、Unix和Linux这3个操作系统,并且将来有可能会增加新的调度算法和支持新的操作系统,请选择恰当的设计模式解决该问题,画出类图,写出关键代码。
// 调度算法接口
interface SchedulingAlgorithm {
void schedule();
}
// 时间片调度
class TimeSliceScheduling implements SchedulingAlgorithm {
@Override
public void schedule() {
System.out.println("时间片调度算法");
}
}
// 抢占调度
class PreemptiveScheduling implements SchedulingAlgorithm {
@Override
public void schedule() {
System.out.println("抢占调度算法");
}
}
// 操作系统抽象类
abstract class OperatingSystem {
protected SchedulingAlgorithm schedulingAlgorithm;
public OperatingSystem(SchedulingAlgorithm algorithm) {
this.schedulingAlgorithm = algorithm;
}
public abstract void executeScheduling();
}
// Windows系统
class WindowsOS extends OperatingSystem {
public WindowsOS(SchedulingAlgorithm algorithm) {
super(algorithm);
}
@Override
public void executeScheduling() {
System.out.println("Windows系统:");
schedulingAlgorithm.schedule();
}
}
// Unix系统
class UnixOS extends OperatingSystem {
public UnixOS(SchedulingAlgorithm algorithm) {
super(algorithm);
}
@Override
public void executeScheduling() {
System.out.println("Unix系统:");
schedulingAlgorithm.schedule();
}
}
// Linux系统
class LinuxOS extends OperatingSystem {
public LinuxOS(SchedulingAlgorithm algorithm) {
super(algorithm);
}
@Override
public void executeScheduling() {
System.out.println("Linux系统:");
schedulingAlgorithm.schedule();
}
}
// 操作系统工厂
class OSFactory {
public static OperatingSystem createOS(String type, SchedulingAlgorithm algorithm) {
switch (type) {
case "Windows":
return new WindowsOS(algorithm);
case "Unix":
return new UnixOS(algorithm);
case "Linux":
return new LinuxOS(algorithm);
default:
throw new IllegalArgumentException("不支持的操作系统类型");
}
}
}
public class Client {
public static void main(String[] args) {
SchedulingAlgorithm timeSlice = new TimeSliceScheduling();
SchedulingAlgorithm preemptive = new PreemptiveScheduling();
OperatingSystem windows = OSFactory.createOS("Windows", timeSlice);
OperatingSystem linux = OSFactory.createOS("Linux", preemptive);
windows.executeScheduling();
linux.executeScheduling();
}
}请设计一个图形编辑器,支持绘制多种图形(圆形、矩形、三角形等),并且支持撤销、重做操作。
import java.util.Stack;
// 图形接口
interface Shape {
void draw();
}
// 圆形
class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
// 矩形
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}
// 三角形
class Triangle implements Shape {
@Override
public void draw() {
System.out.println("绘制三角形");
}
}
// 图形工厂
class ShapeFactory {
public static Shape createShape(String type) {
switch (type) {
case "circle":
return new Circle();
case "rectangle":
return new Rectangle();
case "triangle":
return new Triangle();
default:
throw new IllegalArgumentException("不支持的图形类型");
}
}
}
// 命令接口
interface Command {
void execute();
void undo();
}
// 绘制命令
class DrawCommand implements Command {
private Shape shape;
public DrawCommand(Shape shape) {
this.shape = shape;
}
@Override
public void execute() {
shape.draw();
}
@Override
public void undo() {
System.out.println("撤销绘制");
}
}
// 命令执行者
class Invoker {
private Stack<Command> undoStack = new Stack<>();
private Stack<Command> redoStack = new Stack<>();
public void executeCommand(Command command) {
command.execute();
undoStack.push(command);
redoStack.clear();
}
public void undo() {
if (!undoStack.isEmpty()) {
Command command = undoStack.pop();
command.undo();
redoStack.push(command);
}
}
public void redo() {
if (!redoStack.isEmpty()) {
Command command = redoStack.pop();
command.execute();
undoStack.push(command);
}
}
}
// 编辑器
class GraphicsEditor {
private Invoker invoker = new Invoker();
public void drawShape(String shapeType) {
Shape shape = ShapeFactory.createShape(shapeType);
Command command = new DrawCommand(shape);
invoker.executeCommand(command);
}
public void undo() {
invoker.undo();
}
public void redo() {
invoker.redo();
}
}
public class Client {
public static void main(String[] args) {
GraphicsEditor editor = new GraphicsEditor();
editor.drawShape("circle");
editor.drawShape("rectangle");
editor.undo();
editor.redo();
}
}请设计一个日志系统,支持多种日志输出方式(控制台、文件、数据库等),并且支持不同的日志级别(DEBUG、INFO、WARN、ERROR)。
import java.util.ArrayList;
import java.util.List;
// 日志级别
enum LogLevel {
DEBUG, INFO, WARN, ERROR
}
// 日志事件
class LogEvent {
private String message;
private LogLevel level;
private long timestamp;
public LogEvent(String message, LogLevel level) {
this.message = message;
this.level = level;
this.timestamp = System.currentTimeMillis();
}
// getters
public String getMessage() { return message; }
public LogLevel getLevel() { return level; }
public long getTimestamp() { return timestamp; }
}
// 日志观察者接口
interface LogObserver {
void log(LogEvent event);
}
// 控制台输出
class ConsoleLogger implements LogObserver {
@Override
public void log(LogEvent event) {
System.out.println("[" + event.getLevel() + "] " + event.getMessage());
}
}
// 文件输出
class FileLogger implements LogObserver {
@Override
public void log(LogEvent event) {
// 写入文件
System.out.println("File: [" + event.getLevel() + "] " + event.getMessage());
}
}
// 数据库输出
class DatabaseLogger implements LogObserver {
@Override
public void log(LogEvent event) {
// 写入数据库
System.out.println("DB: [" + event.getLevel() + "] " + event.getMessage());
}
}
// 日志主题
class LoggerSubject {
private List<LogObserver> observers = new ArrayList<>();
private LogLevel level;
public void setLevel(LogLevel level) {
this.level = level;
}
public void addObserver(LogObserver observer) {
observers.add(observer);
}
public void removeObserver(LogObserver observer) {
observers.remove(observer);
}
public void log(LogLevel level, String message) {
if (level.ordinal() >= this.level.ordinal()) {
LogEvent event = new LogEvent(message, level);
notifyObservers(event);
}
}
private void notifyObservers(LogEvent event) {
for (LogObserver observer : observers) {
observer.log(event);
}
}
// 便捷方法
public void debug(String message) { log(LogLevel.DEBUG, message); }
public void info(String message) { log(LogLevel.INFO, message); }
public void warn(String message) { log(LogLevel.WARN, message); }
public void error(String message) { log(LogLevel.ERROR, message); }
}
public class Client {
public static void main(String[] args) {
LoggerSubject logger = new LoggerSubject();
logger.setLevel(LogLevel.INFO);
logger.addObserver(new ConsoleLogger());
logger.addObserver(new FileLogger());
logger.debug("调试信息"); // 不会输出
logger.info("普通信息");
logger.error("错误信息");
}
}请设计一个缓存系统,支持LRU(最近最少使用)淘汰策略,并且支持多种缓存存储方式(内存、磁盘、分布式等)。
import java.util.LinkedHashMap;
import java.util.Map;
// 缓存存储接口
interface CacheStorage {
Object get(String key);
void put(String key, Object value);
void remove(String key);
boolean containsKey(String key);
}
// 内存缓存
class MemoryCache implements CacheStorage {
private Map<String, Object> cache = new LinkedHashMap<>();
@Override
public Object get(String key) {
return cache.get(key);
}
@Override
public void put(String key, Object value) {
cache.put(key, value);
}
@Override
public void remove(String key) {
cache.remove(key);
}
@Override
public boolean containsKey(String key) {
return cache.containsKey(key);
}
}
// 磁盘缓存
class DiskCache implements CacheStorage {
@Override
public Object get(String key) {
// 从磁盘读取
return null;
}
@Override
public void put(String key, Object value) {
// 写入磁盘
}
@Override
public void remove(String key) {
// 从磁盘删除
}
@Override
public boolean containsKey(String key) {
// 检查磁盘
return false;
}
}
// LRU缓存装饰器
class LRUCacheDecorator implements CacheStorage {
private CacheStorage cacheStorage;
private LinkedHashMap<String, Object> lruMap;
private int capacity;
public LRUCacheDecorator(CacheStorage cacheStorage, int capacity) {
this.cacheStorage = cacheStorage;
this.capacity = capacity;
this.lruMap = new LinkedHashMap<String, Object>(capacity, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<String, Object> eldest) {
if (size() > capacity) {
cacheStorage.remove(eldest.getKey());
return true;
}
return false;
}
};
}
@Override
public Object get(String key) {
Object value = cacheStorage.get(key);
if (value != null) {
lruMap.get(key); // 更新访问顺序
}
return value;
}
@Override
public void put(String key, Object value) {
cacheStorage.put(key, value);
lruMap.put(key, value);
}
@Override
public void remove(String key) {
cacheStorage.remove(key);
lruMap.remove(key);
}
@Override
public boolean containsKey(String key) {
return cacheStorage.containsKey(key);
}
}
// 缓存管理器
class CacheManager {
private CacheStorage cache;
public CacheManager(CacheStorage cache) {
this.cache = cache;
}
public Object get(String key) {
return cache.get(key);
}
public void put(String key, Object value) {
cache.put(key, value);
}
public void remove(String key) {
cache.remove(key);
}
}
public class Client {
public static void main(String[] args) {
CacheStorage memoryCache = new MemoryCache();
CacheStorage lruCache = new LRUCacheDecorator(memoryCache, 3);
CacheManager cacheManager = new CacheManager(lruCache);
cacheManager.put("key1", "value1");
cacheManager.put("key2", "value2");
cacheManager.put("key3", "value3");
System.out.println(cacheManager.get("key1")); // value1
cacheManager.put("key4", "value4"); // key2被淘汰
System.out.println(cacheManager.get("key2")); // null
}
}本指南涵盖了多种设计模式的应用实例,包括:
- 创建型模式:工厂模式、抽象工厂模式、建造者模式、单例模式
- 结构型模式:适配器模式、装饰器模式
- 行为型模式:策略模式、命令模式、观察者模式
通过这些作业和真题的练习,可以帮助你深入理解设计模式的原理和应用场景,提高面向对象设计能力。











