创建型模式
1. 工厂方法模式(Factory Method)
工厂方法模式通过定义一个创建对象的接口,让子类决定实例化哪一个类。下面的示例展示了一个文档编辑器可以创建不同类型的文档。
// Product Interface interface Document { void open(); void save(); } // Concrete Product A class WordDocument implements Document { @Override public void open() { System.out.println("Opening Word document..."); } @Override public void save() { System.out.println("Saving Word document..."); } } // Concrete Product B class PdfDocument implements Document { @Override public void open() { System.out.println("Opening PDF document..."); } @Override public void save() { System.out.println("Saving PDF document..."); } } // Creator abstract class Application { abstract Document createDocument(); public void openDocument() { Document doc = createDocument(); doc.open(); } } // Concrete Creator A class WordApplication extends Application { @Override Document createDocument() { return new WordDocument(); } } // Concrete Creator B class PdfApplication extends Application { @Override Document createDocument() { return new PdfDocument(); } } // Client code public class FactoryMethodExample { public static void main(String[] args) { Application app = new WordApplication(); app.openDocument(); // Output: Opening Word document... app = new PdfApplication(); app.openDocument(); // Output: Opening PDF document... } }
2. 抽象工厂模式(Abstract Factory)
抽象工厂模式提供一个接口,用于创建相关或依赖的对象家族,而无需明确指定具体类。以下示例展示了一个UI库,可以创建不同风格的按钮和文本框。
// Abstract Product A interface Button { void click(); } // Abstract Product B interface TextField { void type(String text); } // Concrete Product A1 class WindowsButton implements Button { @Override public void click() { System.out.println("Windows Button clicked."); } } // Concrete Product B1 class WindowsTextField implements TextField { @Override public void type(String text) { System.out.println("Windows TextField typed: " + text); } } // Concrete Product A2 class MacButton implements Button { @Override public void click() { System.out.println("Mac Button clicked."); } } // Concrete Product B2 class MacTextField implements TextField { @Override public void type(String text) { System.out.println("Mac TextField typed: " + text); } } // Abstract Factory interface GUIFactory { Button createButton(); TextField createTextField(); } // Concrete Factory 1 class WindowsFactory implements GUIFactory { @Override public Button createButton() { return new WindowsButton(); } @Override public TextField createTextField() { return new WindowsTextField(); } } // Concrete Factory 2 class MacFactory implements GUIFactory { @Override public Button createButton() { return new MacButton(); } @Override public TextField createTextField() { return new MacTextField(); } } // Client public class AbstractFactoryExample { private Button button; private TextField textField; public AbstractFactoryExample(GUIFactory factory) { button = factory.createButton(); textField = factory.createTextField(); } public void interact() { button.click(); textField.type("Hello, Abstract Factory!"); } public static void main(String[] args) { GUIFactory factory = new WindowsFactory(); AbstractFactoryExample example = new AbstractFactoryExample(factory); example.interact(); // Windows Button clicked, Windows TextField typed: Hello, Abstract Factory! factory = new MacFactory(); example = new AbstractFactoryExample(factory); example.interact(); // Mac Button clicked, Mac TextField typed: Hello, Abstract Factory! } }
3. 单例模式(Singleton)
单例模式确保一个类只有一个实例,并提供一个全局访问点。以下示例展示了一个简单的单例模式实现。
public class Singleton { private static volatile Singleton instance; private Singleton() { // private constructor to prevent instantiation } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } public void doSomething() { System.out.println("Doing something with Singleton."); } public static void main(String[] args) { Singleton singleton = Singleton.getInstance(); singleton.doSomething(); // Output: Doing something with Singleton. } }
4. 建造者模式(Builder)
建造者模式用于创建复杂对象的实例化过程,将其与表示分离。以下示例展示了创建一个复杂的House
对象的过程。
// Product class House { private String foundation; private String structure; private String roof; private boolean furnished; public void setFoundation(String foundation) { this.foundation = foundation; } public void setStructure(String structure) { this.structure = structure; } public void setRoof(String roof) { this.roof = roof; } public void setFurnished(boolean furnished) { this.furnished = furnished; } @Override public String toString() { return "House [foundation=" + foundation + ", structure=" + structure + ", roof=" + roof + ", furnished=" + furnished + "]"; } } // Builder Interface interface HouseBuilder { void buildFoundation(); void buildStructure(); void buildRoof(); void furnishHouse(); House getHouse(); } // Concrete Builder class ConcreteHouseBuilder implements HouseBuilder { private House house; public ConcreteHouseBuilder() { this.house = new House(); } @Override public void buildFoundation() { house.setFoundation("Concrete Foundation"); System.out.println("ConcreteHouseBuilder: Building concrete foundation."); } @Override public void buildStructure() { house.setStructure("Concrete Structure"); System.out.println("ConcreteHouseBuilder: Building concrete structure."); } @Override public void buildRoof() { house.setRoof("Concrete Roof"); System.out.println("ConcreteHouseBuilder: Building concrete roof."); } @Override public void furnishHouse() { house.setFurnished(true); System.out.println("ConcreteHouseBuilder: Furnishing the house."); } @Override public House getHouse() { return this.house; } } // Director class ConstructionEngineer { private HouseBuilder houseBuilder; public ConstructionEngineer(HouseBuilder houseBuilder) { this.houseBuilder = houseBuilder; } public House constructHouse() { houseBuilder.buildFoundation(); houseBuilder.buildStructure(); houseBuilder.buildRoof(); houseBuilder.furnishHouse(); return houseBuilder.getHouse(); } } // Client public class BuilderExample { public static void main(String[] args) { HouseBuilder builder = new ConcreteHouseBuilder(); ConstructionEngineer engineer = new ConstructionEngineer(builder); House house = engineer.constructHouse(); System.out.println("Constructed House: " + house); } }
5. 原型模式(Prototype)
原型模式用于通过复制现有对象来创建新的对象。以下示例展示了一个简单的原型模式实现。
// Prototype Interface interface Prototype extends Cloneable { Prototype clone(); } // Concrete Prototype class ConcretePrototype implements Prototype { private String field; public ConcretePrototype(String field) { this.field = field; } @Override public Prototype clone() { return new ConcretePrototype(this.field); } @Override public String toString() { return "ConcretePrototype [field=" + field + "]"; } } // Client public class PrototypeExample { public static void main(String[] args) { ConcretePrototype original = new ConcretePrototype("Original"); ConcretePrototype clone = (ConcretePrototype) original.clone(); System.out.println(original); // Output: ConcretePrototype [field=Original] System.out.println(clone); // Output: ConcretePrototype [field=Original] } }
结构型模式
6. 适配器模式(Adapter)
适配器模式将一个类的接口转换成客户期望的另一个接口。以下示例展示了如何适配一个旧的API到新的接口中。
// Old interface class OldPrinter { void print(String text) { System.out.println("Old Printer: " + text); } } // Target interface interface NewPrinter { void print(String text); } // Adapter class PrinterAdapter implements NewPrinter { private OldPrinter oldPrinter; public PrinterAdapter(OldPrinter oldPrinter) { this.oldPrinter = oldPrinter; } @Override public void print(String text) { oldPrinter.print(text); } } // Client public class AdapterExample { public static void main(String[] args) { OldPrinter oldPrinter = new OldPrinter(); NewPrinter newPrinter = new PrinterAdapter(oldPrinter); newPrinter.print("Hello, Adapter Pattern!"); // Output: Old Printer: Hello, Adapter Pattern! } }
7. 桥接模式(Bridge)
桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。以下示例展示了使用桥接模式将绘图功能与不同形状分离。
// Implementor Interface interface DrawAPI { void drawCircle(int radius, int x, int y); } // Concrete Implementor A class RedCircle implements DrawAPI { @Override public void drawCircle(int radius, int x, int y) { System.out.println("Drawing Circle [color: red, radius: " + radius + ", x: " + x + ", y: " + y + "]"); } } // Concrete Implementor B class GreenCircle implements DrawAPI { @Override public void drawCircle(int radius, int x, int y) { System.out.println("Drawing Circle [color: green, radius: " + radius + ", x: " + x + ", y: " + y + "]"); } } // Abstraction abstract class Shape { protected DrawAPI drawAPI; protected Shape(DrawAPI drawAPI) { this.drawAPI = drawAPI; } public abstract void draw(); } // Refined Abstraction class Circle extends Shape { private int radius, x, y; protected Circle(int radius, int x, int y, DrawAPI drawAPI) { super(drawAPI); this.radius = radius; this.x = x; this.y = y; } @Override public void draw() { drawAPI.drawCircle(radius, x, y); } } // Client public class BridgeExample { public static void main(String[] args) { Shape redCircle = new Circle(10, 100, 100, new RedCircle()); Shape greenCircle = new Circle(10, 200, 200, new GreenCircle()); redCircle.draw(); // Output: Drawing Circle [color: red, radius: 10, x: 100, y: 100] greenCircle.draw(); // Output: Drawing Circle [color: green, radius: 10, x: 200, y: 200] } }
8. 组合模式(Composite)
组合模式将对象组合成树形结构以表示部分-整体的层次结构。以下示例展示了如何使用组合模式表示文件系统。
// Component interface FileSystemComponent { void showDetails(); } // Leaf class File implements FileSystemComponent { private String name; public File(String name) { this.name = name; } @Override public void showDetails() { System.out.println("File: " + name); } } // Composite class Directory implements FileSystemComponent { private String name; private List<FileSystemComponent> components = new ArrayList<>(); public Directory(String name) { this.name = name; } public void addComponent(FileSystemComponent component) { components.add(component); } public void removeComponent(FileSystemComponent component) { components.remove(component); } @Override public void showDetails() { System.out.println("Directory: " + name); for (FileSystemComponent component : components) { component.showDetails(); } } } // Client public class CompositeExample { public static void main(String[] args) { FileSystemComponent file1 = new File("file1.txt"); FileSystemComponent file2 = new File("file2.txt"); FileSystemComponent file3 = new File("file3.txt"); Directory directory1 = new Directory("dir1"); directory1.addComponent(file1); Directory directory2 = new Directory("dir2"); directory2.addComponent(file2); directory2.addComponent(file3); directory2.addComponent(directory1); directory2.showDetails(); // Output: // Directory: dir2 // File: file2.txt // File: file3.txt // Directory: dir1 // File: file1.txt } }
9. 装饰器模式(Decorator)
装饰器模式动态地给一个对象添加一些额外的职责。以下示例展示了如何装饰一个文本输出。
// Component Interface interface TextComponent { String formatText(); } // Concrete Component class PlainText implements TextComponent { private String text; public PlainText(String text) { this.text = text; } @Override public String formatText() { return text; } } // Decorator abstract class TextDecorator implements TextComponent { protected TextComponent decoratedText; public TextDecorator(TextComponent decoratedText) { this.decoratedText = decoratedText; } public String formatText() { return decoratedText.formatText(); } } // Concrete Decorator class BoldDecorator extends TextDecorator { public BoldDecorator(TextComponent decoratedText) { super(decoratedText); } @Override public String formatText() { return "<b>" + super.formatText() + "</b>"; } } // Another Concrete Decorator class ItalicDecorator extends TextDecorator { public ItalicDecorator(TextComponent decoratedText) { super(decoratedText); } @Override public String formatText() { return "<i>" + super.formatText() + "</i>"; } } // Client public class DecoratorExample { public static void main(String[] args) { TextComponent plainText = new PlainText("Hello, Decorator Pattern!"); TextComponent boldText = new BoldDecorator(plainText); TextComponent italicText = new ItalicDecorator(plainText); TextComponent boldItalicText = new ItalicDecorator(boldText); System.out.println(plainText.formatText()); // Output: Hello, Decorator Pattern! System.out.println(boldText.formatText()); // Output: <b>Hello, Decorator Pattern!</b> System.out.println(italicText.formatText()); // Output: <i>Hello, Decorator Pattern!</i> System.out.println(boldItalicText.formatText()); // Output: <i><b>Hello, Decorator Pattern!</b></i> } }
10. 外观模式(Facade)
外观模式为子系统中的一组接口提供一个一致的界面。以下示例展示了一个简单的外观类,用于控制家庭影院系统的多个子系统。
// Subsystem Class A class DVDPlayer { public void on() { System.out.println("DVD Player is ON"); } public void play(String movie) { System.out.println("Playing movie: " + movie); } public void off() { System.out.println("DVD Player is OFF"); } } // Subsystem Class B class Amplifier { public void on() { System.out.println("Amplifier is ON"); } public void setVolume(int level) { System.out.println("Setting volume to " + level); } public void off() { System.out.println("Amplifier is OFF"); } } // Subsystem Class C class Projector { public void on() { System.out.println("Projector is ON"); } public void setInput(String input) { System.out.println("Setting input to " + input); } public void off() { System.out.println("Projector is OFF"); } } // Facade class HomeTheaterFacade { private DVDPlayer dvdPlayer; private Amplifier amplifier; private Projector projector; public HomeTheaterFacade(DVDPlayer dvdPlayer, Amplifier amplifier, Projector projector) { this.dvdPlayer = dvdPlayer; this.amplifier = amplifier; this.projector = projector; } public void watchMovie(String movie) { System.out.println("Get ready to watch a movie..."); dvdPlayer.on(); dvdPlayer.play(movie); amplifier.on(); amplifier.setVolume(5); projector.on(); projector.setInput("DVD"); } public void endMovie() { System.out.println("Shutting down the movie theater..."); dvdPlayer.off(); amplifier.off(); projector.off(); } } // Client public class FacadeExample { public static void main(String[] args) { DVDPlayer dvdPlayer = new DVDPlayer(); Amplifier amplifier = new Amplifier(); Projector projector = new Projector(); HomeTheaterFacade homeTheater = new HomeTheaterFacade(dvdPlayer, amplifier, projector); homeTheater.watchMovie("Inception"); // Output: // Get ready to watch a movie... // DVD Player is ON // Playing movie: Inception // Amplifier is ON // Setting volume to 5 // Projector is ON // Setting input to DVD homeTheater.endMovie(); // Output: // Shutting down the movie theater... // DVD Player is OFF // Amplifier is OFF // Projector is OFF } }
11. 享元模式(Flyweight)
享元模式通过共享尽可能多的对象以减少内存消耗。以下示例展示了一个字符的字体样式共享的场景。
import java.util.HashMap; import java.util.Map; // Flyweight class Font { private String fontName; private int size; public Font(String fontName, int size) { this.fontName = fontName; this.size = size; } public String getFontName() { return fontName; } public int getSize() { return size; } @Override public String toString() { return "Font[name=" + fontName + ", size=" + size + "]"; } } // Flyweight Factory class FontFactory { private Map<String, Font> fontMap = new HashMap<>(); public Font getFont(String fontName, int size) { String key = fontName + size; Font font = fontMap.get(key); if (font == null) { font = new Font(fontName, size); fontMap.put(key, font); } return font; } } // Client class Character { private char value; private Font font; public Character(char value, Font font) { this.value = value; this.font = font; } public void display() { System.out.println("Character: " + value + " with font: " + font); } } public class FlyweightExample { public static void main(String[] args) { FontFactory fontFactory = new FontFactory(); Font font1 = fontFactory.getFont("Arial", 12); Font font2 = fontFactory.getFont("Arial", 12); Font font3 = fontFactory.getFont("Arial", 14); Character characterA = new Character('A', font1); Character characterB = new Character('B', font2); Character characterC = new Character('C', font3); characterA.display(); // Character: A with font: Font[name=Arial, size=12] characterB.display(); // Character: B with font: Font[name=Arial, size=12] characterC.display(); // Character: C with font: Font[name=Arial, size=14] // Checking object sharing System.out.println("font1 == font2: " + (font1 == font2)); // true System.out.println("font1 == font3: " + (font1 == font3)); // false } }
12. 代理模式(Proxy)
代理模式为其他对象提供一种代理,以控制对这个对象的访问。以下示例展示了一个保护代理,用于控制对敏感操作的访问。
// Subject Interface interface Image { void display(); } // Real Subject class RealImage implements Image { private String fileName; public RealImage(String fileName) { this.fileName = fileName; loadFromDisk(); } private void loadFromDisk() { System.out.println("Loading " + fileName); } @Override public void display() { System.out.println("Displaying " + fileName); } } // Proxy 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(); } } // Client public class ProxyExample { public static void main(String[] args) { Image image1 = new ProxyImage("photo1.jpg"); Image image2 = new ProxyImage("photo2.jpg"); // Image will be loaded from disk and displayed image1.display(); // Output: Loading photo1.jpg, Displaying photo1.jpg // Image will not be loaded from disk, only displayed image1.display(); // Output: Displaying photo1.jpg // Image will be loaded from disk and displayed image2.display(); // Output: Loading photo2.jpg, Displaying photo2.jpg } }
行为型模式
13. 责任链模式(Chain of Responsibility)
责任链模式将请求的发送者和接受者解耦,使多个对象都有机会处理该请求。以下示例展示了一个支持不同日志级别的日志记录系统。
// Handler abstract class Logger { public static int INFO = 1; public static int DEBUG = 2; public static int ERROR = 3; protected int level; // Next element in chain of responsibility 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); } // Concrete Handler for Info class InfoLogger extends Logger { public InfoLogger(int level) { this.level = level; } @Override protected void write(String message) { System.out.println("Info: " + message); } } // Concrete Handler for Debug class DebugLogger extends Logger { public DebugLogger(int level) { this.level = level; } @Override protected void write(String message) { System.out.println("Debug: " + message); } } // Concrete Handler for Error class ErrorLogger extends Logger { public ErrorLogger(int level) { this.level = level; } @Override protected void write(String message) { System.out.println("Error: " + message); } } // Client public class ChainOfResponsibilityExample { private static Logger getChainOfLoggers() { Logger errorLogger = new ErrorLogger(Logger.ERROR); Logger debugLogger = new DebugLogger(Logger.DEBUG); Logger infoLogger = new InfoLogger(Logger.INFO); infoLogger.setNextLogger(debugLogger); debugLogger.setNextLogger(errorLogger); return infoLogger; } public static void main(String[] args) { Logger loggerChain = getChainOfLoggers(); loggerChain.logMessage(Logger.INFO, "This is an information."); // Output: Info: This is an information. loggerChain.logMessage(Logger.DEBUG, "This is a debug level information."); // Output: Info: This is a debug level information. // Debug: This is a debug level information. loggerChain.logMessage(Logger.ERROR, "This is an error information."); // Output: Info: This is an error information. // Debug: This is an error information. // Error: This is an error information. } }
14. 命令模式(Command)
命令模式将请求封装成对象,从而使您可以用不同的请求对客户端进行参数化。以下示例展示了一个简单的遥控器实现,用于执行各种设备操作。
// Command Interface interface Command { void execute(); } // Receiver class Light { public void on() { System.out.println("Light is ON"); } public void off() { System.out.println("Light is OFF"); } } // Concrete Command for turning on the light class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } @Override public void execute() { light.on(); } } // Concrete Command for turning off the light class LightOffCommand implements Command { private Light light; public LightOffCommand(Light light) { this.light = light; } @Override public void execute() { light.off(); } } // Invoker class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } } // Client public class CommandExample { public static void main(String[] args) { Light light = new Light(); Command lightOn = new LightOnCommand(light); Command lightOff = new LightOffCommand(light); RemoteControl remote = new RemoteControl(); remote.setCommand(lightOn); remote.pressButton(); // Output: Light is ON remote.setCommand(lightOff); remote.pressButton(); // Output: Light is OFF } }
15. 解释器模式(Interpreter)
解释器模式为一种语言定义其文法,并为该语言中的文法表达式提供一个解释器。以下示例展示了一个简单的表达式解析器。
// Abstract Expression interface Expression { boolean interpret(String context); } // Terminal Expression class TerminalExpression implements Expression { private String data; public TerminalExpression(String data) { this.data = data; } @Override public boolean interpret(String context) { return context.contains(data); } } // Or Expression class OrExpression implements Expression { private Expression expr1; private Expression expr2; public OrExpression(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } @Override public boolean interpret(String context) { return expr1.interpret(context) || expr2.interpret(context); } } // And Expression class AndExpression implements Expression { private Expression expr1; private Expression expr2; public AndExpression(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } @Override public boolean interpret(String context) { return expr1.interpret(context) && expr2.interpret(context); } } // Client public class InterpreterExample { // Rule: "John" or "Julie" are male public static Expression getMaleExpression() { Expression john = new TerminalExpression("John"); Expression julie = new TerminalExpression("Julie"); return new OrExpression(john, julie); } // Rule: "Married" and "Julie" are married women public static Expression getMarriedWomanExpression() { Expression julie = new TerminalExpression("Julie"); Expression married = new TerminalExpression("Married"); return new AndExpression(julie, married); } public static void main(String[] args) { Expression isMale = getMaleExpression(); Expression isMarriedWoman = getMarriedWomanExpression(); System.out.println("John is male? " + isMale.interpret("John")); // Output: John is male? true System.out.println("Julie is a married woman? " + isMarriedWoman.interpret("Married Julie")); // Output: Julie is a married woman? true System.out.println("Julie is male? " + isMale.interpret("Julie")); // Output: Julie is male? true System.out.println("Married John is a married woman? " + isMarriedWoman.interpret("Married John")); // Output: Married John is a married woman? false } }
16. 迭代器模式(Iterator)
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。以下示例展示了一个简单的自定义聚合类及其迭代器。
import java.util.Iterator; // Aggregate Interface interface Container { Iterator<String> getIterator(); } // Concrete Aggregate class NameRepository implements Container { private String[] names = {"John", "Jane", "Julie", "Jake"}; @Override public Iterator<String> getIterator() { return new NameIterator(); } // Concrete Iterator private class NameIterator implements Iterator<String> { int index = 0; @Override public boolean hasNext() { return index < names.length; } @Override public String next() { if (this.hasNext()) { return names[index++]; } return null; } } } // Client public class IteratorExample { public static void main(String[] args) { NameRepository nameRepository = new NameRepository(); for (Iterator<String> iter = nameRepository.getIterator(); iter.hasNext(); ) { String name = iter.next(); System.out.println("Name : " + name); } // Output: // Name : John // Name : Jane // Name : Julie // Name : Jake } }
17. 中介者模式(Mediator)
中介者模式定义一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。以下示例展示了一个聊天系统的实现。
import java.util.ArrayList; import java.util.List; // Mediator Interface interface ChatMediator { void sendMessage(String message, User user); void addUser(User user); } // Concrete Mediator class ChatMediatorImpl implements ChatMediator { private List<User> users; public ChatMediatorImpl() { this.users = new ArrayList<>(); } @Override public void addUser(User user) { this.users.add(user); } @Override public void sendMessage(String message, User user) { for (User u : this.users) { // Message should not be received by the user sending it if (u != user) { u.receive(message); } } } } // Colleague Abstract Class abstract class User { protected ChatMediator mediator; protected String name; public User(ChatMediator mediator, String name) { this.mediator = mediator; this.name = name; } public abstract void send(String message); public abstract void receive(String message); } // Concrete Colleague class UserImpl extends User { public UserImpl(ChatMediator mediator, String name) { super(mediator, name); } @Override public void send(String message) { System.out.println(this.name + ": Sending Message = " + message); mediator.sendMessage(message, this); } @Override public void receive(String message) { System.out.println(this.name + ": Received Message = " + message); } } // Client public class MediatorExample { public static void main(String[] args) { ChatMediator mediator = new ChatMediatorImpl(); User john = new UserImpl(mediator, "John"); User jane = new UserImpl(mediator, "Jane"); User bob = new UserImpl(mediator, "Bob"); mediator.addUser(john); mediator.addUser(jane); mediator.addUser(bob); john.send("Hi everyone!"); // Output: // John: Sending Message = Hi everyone! // Jane: Received Message = Hi everyone! // Bob: Received Message = Hi everyone! } }
18. 备忘录模式(Memento)
备忘录模式用于保存对象的状态,以便可以在以后恢复。以下示例展示了一个文本编辑器的撤销操作。
import java.util.Stack; // Memento class TextMemento { private String text; public TextMemento(String text) { this.text = text; } public String getText() { return text; } } // Originator class TextEditor { private StringBuilder text; public TextEditor() { this.text = new StringBuilder(); } public void write(String newText) { text.append(newText); } public String getText() { return text.toString(); } public TextMemento save() { return new TextMemento(text.toString()); } public void undoToLastSave(Object obj) { TextMemento memento = (TextMemento) obj; text = new StringBuilder(memento.getText()); } } // Caretaker class Caretaker { private Stack<TextMemento> mementoStack = new Stack<>(); public void save(TextEditor textEditor) { mementoStack.push(textEditor.save()); } public void undo(TextEditor textEditor) { if (!mementoStack.isEmpty()) { textEditor.undoToLastSave(mementoStack.pop()); } } } // Client public class MementoExample { public static void main(String[] args) { TextEditor textEditor = new TextEditor(); Caretaker caretaker = new Caretaker(); textEditor.write("Hello, "); caretaker.save(textEditor); textEditor.write("World!"); System.out.println(textEditor.getText()); // Output: Hello, World! caretaker.undo(textEditor); System.out.println(textEditor.getText()); // Output: Hello, caretaker.undo(textEditor); System.out.println(textEditor.getText()); // Output: Hello, } }
19. 观察者模式(Observer)
观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态改变时,所有依赖于它的对象都会得到通知并自动更新。以下示例展示了一个天气系统的实现。
import java.util.ArrayList; import java.util.List; // Subject class WeatherStation { private List<Observer> observers = new ArrayList<>(); private int temperature; public void addObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void setTemperature(int temperature) { this.temperature = temperature; notifyObservers(); } public int getTemperature() { return temperature; } private void notifyObservers() { for (Observer observer : observers) { observer.update(); } } } // Observer Interface interface Observer { void update(); } // Concrete Observer class Display implements Observer { private WeatherStation weatherStation; public Display(WeatherStation weatherStation) { this.weatherStation = weatherStation; } @Override public void update() { System.out.println("Temperature updated to: " + weatherStation.getTemperature() + " degrees"); } } // Client public class ObserverExample { public static void main(String[] args) { WeatherStation weatherStation = new WeatherStation(); Display display1 = new Display(weatherStation); Display display2 = new Display(weatherStation); weatherStation.addObserver(display1); weatherStation.addObserver(display2); weatherStation.setTemperature(25); // Output: // Temperature updated to: 25 degrees // Temperature updated to: 25 degrees weatherStation.setTemperature(30); // Output: // Temperature updated to: 30 degrees // Temperature updated to: 30 degrees } }
20. 状态模式(State)
状态模式允许对象在内部状态改变时改变其行为。以下示例展示了一个简单的电灯开关的状态切换。
// State Interface interface State { void pressSwitch(LightSwitch lightSwitch); } // Concrete State: On class OnState implements State { @Override public void pressSwitch(LightSwitch lightSwitch) { System.out.println("Turning off the light."); lightSwitch.setState(new OffState()); } } // Concrete State: Off class OffState implements State { @Override public void pressSwitch(LightSwitch lightSwitch) { System.out.println("Turning on the light."); lightSwitch.setState(new OnState()); } } // Context class LightSwitch { private State state; public LightSwitch() { state = new OffState(); // Initial state } public void setState(State state) { this.state = state; } public void pressSwitch() { state.pressSwitch(this); } } // Client public class StateExample { public static void main(String[] args) { LightSwitch lightSwitch = new LightSwitch(); lightSwitch.pressSwitch(); // Output: Turning on the light. lightSwitch.pressSwitch(); // Output: Turning off the light. } }
21. 策略模式(Strategy)
策略模式定义一系列算法,将每个算法封装起来,并使它们可以互换。以下示例展示了一个支付系统的实现,其中使用不同的支付方式。
// Strategy Interface interface PaymentStrategy { void pay(int amount); } // Concrete Strategy: CreditCard class CreditCardPayment implements PaymentStrategy { private String cardNumber; public CreditCardPayment(String cardNumber) { this.cardNumber = cardNumber; } @Override public void pay(int amount) { System.out.println("Paid " + amount + " using Credit Card."); } } // Concrete Strategy: PayPal class PayPalPayment implements PaymentStrategy { private String email; public PayPalPayment(String email) { this.email = email; } @Override public void pay(int amount) { System.out.println("Paid " + amount + " using PayPal."); } } // Context class ShoppingCart { private PaymentStrategy paymentStrategy; public void setPaymentStrategy(PaymentStrategy paymentStrategy) { this.paymentStrategy = paymentStrategy; } public void checkout(int amount) { paymentStrategy.pay(amount); } } // Client public class StrategyExample { public static void main(String[] args) { ShoppingCart cart = new ShoppingCart(); cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9876-5432")); cart.checkout(100); // Output: Paid 100 using Credit Card. cart.setPaymentStrategy(new PayPalPayment("email@example.com")); cart.checkout(200); // Output: Paid 200 using PayPal. } }
22. 模板方法模式(Template Method)
模板方法模式定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变算法结构即可重新定义该算法的某些特定步骤。以下示例展示了一个饮料制作过程的模板方法。
// Abstract Class abstract class Beverage { // Template method public final void prepareRecipe() { boilWater(); brew(); pourInCup(); addCondiments(); } abstract void brew(); abstract void addCondiments(); void boilWater() { System.out.println("Boiling water"); } void pourInCup() { System.out.println("Pouring into cup"); } } // Concrete Class: Tea class Tea extends Beverage { @Override void brew() { System.out.println("Steeping the tea"); } @Override void addCondiments() { System.out.println("Adding lemon"); } } // Concrete Class: Coffee class Coffee extends Beverage { @Override void brew() { System.out.println("Dripping Coffee through filter"); } @Override void addCondiments() { System.out.println("Adding sugar and milk"); } } // Client public class TemplateMethodExample { public static void main(String[] args) { Beverage tea = new Tea(); tea.prepareRecipe(); // Output: // Boiling water // Steeping the tea // Pouring into cup // Adding lemon Beverage coffee = new Coffee(); coffee.prepareRecipe(); // Output: // Boiling water // Dripping Coffee through filter // Pouring into cup // Adding sugar and milk } }
23. 访问者模式(Visitor)
访问者模式允许你为一个对象结构中的各元素添加新功能,而又不改变各元素的类。以下示例展示了一个用于计算购物车中物品价格的访问者模式实现。
// Visitor Interface interface ShoppingCartVisitor { int visit(Book book); int visit(Fruit fruit); } // Concrete Visitor class ShoppingCartVisitorImpl implements ShoppingCartVisitor { @Override public int visit(Book book) { int cost = book.getPrice(); if (cost > 50) { cost -= 5; // Discount for books over $50 } System.out.println("Book ISBN::" + book.getIsbn() + " cost =" + cost); return cost; } @Override public int visit(Fruit fruit) { int cost = fruit.getPricePerKg() * fruit.getWeight(); System.out.println(fruit.getName() + " cost = " + cost); return cost; } } // Element Interface interface ItemElement { int accept(ShoppingCartVisitor visitor); } // Concrete Element: Book class Book implements ItemElement { private int price; private String isbn; public Book(int price, String isbn) { this.price = price; this.isbn = isbn; } public int getPrice() { return price; } public String getIsbn() { return isbn; } @Override public int accept(ShoppingCartVisitor visitor) { return visitor.visit(this); } } // Concrete Element: Fruit class Fruit implements ItemElement { private int pricePerKg; private int weight; private String name; public Fruit(int pricePerKg, int weight, String name) { this.pricePerKg = pricePerKg; this.weight = weight; this.name = name; } public int getPricePerKg() { return pricePerKg; } public int getWeight() { return weight; } public String getName() { return name; } @Override public int accept(ShoppingCartVisitor visitor) { return visitor.visit(this); } } // Client public class VisitorExample { public static void main(String[] args) { ItemElement[] items = new ItemElement[]{ new Book(60, "1234"), new Book(40, "5678"), new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple") }; int total = calculatePrice(items); System.out.println("Total Cost = " + total); // Output: Total Cost = 135 } private static int calculatePrice(ItemElement[] items) { ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl(); int sum = 0; for (ItemElement item : items) { sum += item.accept(visitor); } return sum; } }
这些例子涵盖了设计模式的各个方面,每个模式都用具体的代码实现展示了其应用场景和优点。设计模式不仅仅是代码模板,它们是应对软件设计中常见问题的解决方案。理解这些模式的思想和使用场景将有助于你在实际开发中做出更好的设计决策。
23种设计模式介绍Java之23种设计模式介绍-优快云博客