Creational Design Patterns
Abstract Factory(抽象工厂)
Allows the creation of objects without specifying their concrete type
public class Main {
public static void main(String[] args) {
ShapeFactory factory = new Shape3DFactory(); // or new Shape2DFactory()
Circle circle = factory.createCircle();
Square square = factory.createSquare();
circle.draw();
square.draw();
}
}
// ==== Abstract Products ====
interface Circle {
void draw();
}
interface Square {
void draw();
}
// ==== 2D Concrete Products ====
class Circle2D implements Circle {
public void draw() {
System.out.println("Drawing 2D Circle");
}
}
class Square2D implements Square {
public void draw() {
System.out.println("Drawing 2D Square");
}
}
// ==== 3D Concrete Products ====
class Circle3D implements Circle {
public void draw() {
System.out.println("Rendering 3D Circle");
}
}
class Square3D implements Square {
public void draw() {
System.out.println("Rendering 3D Square");
}
}
// ==== Abstract Factory ====
interface ShapeFactory {
Circle createCircle();
Square createSquare();
}
// ==== Concrete Factories ====
class Shape2DFactory implements ShapeFactory {
public Circle createCircle() {
return new Circle2D();
}
public Square createSquare() {
return new Square2D();
}
}
class Shape3DFactory implements ShapeFactory {
public Circle createCircle() {
return new Circle3D();
}
public Square createSquare() {
return new Square3D();
}
}
Builder(建造者)
Uses to create complex objects
public class Main {
public static void main(String[] args) {
User user = new User.Builder("Alice", "alice@example.com")
.setPhone("123-456-7890")
.setAddress("123 Main St")
.build();
System.out.println(user);
}
}
// ==== User class with Builder ====
class User {
// Required parameters
private final String name;
private final String email;
// Optional parameters
private final String phone;
private final String address;
private User(Builder builder) {
this.name = builder.name;
this.email = builder.email;
this.phone = builder.phone;
this.address = builder.address;
}
@Override
public String toString() {
return "User{name='" + name + "', email='" + email + "', phone='" + phone + "', address='" + address + "'}";
}
// ==== Builder ====
public static class Builder {
private final String name;
private final String email;
private String phone;
private String address;
public Builder(String name, String email) {
this.name = name;
this.email = email;
}
public Builder setPhone(String phone) {
this.phone = phone;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public User build() {
return new User(this);
}
}
}
Factory Method(工厂方法)
Creates objects without specifying the exact class to create.
public class Main {
public static void main(String[] args) {
ShapeFactory circleFactory = new CircleFactory();
Shape circle = circleFactory.createShape();
circle.draw();
ShapeFactory squareFactory = new SquareFactory();
Shape square = squareFactory.createShape();
square.draw();
}
}
// ==== Product Interface ====
interface Shape {
void draw();
}
// ==== Concrete Products ====
class Circle implements Shape {
public void draw() {
System.out.println("Drawing Circle");
}
}
class Square implements Shape {
public void draw() {
System.out.println("Drawing Square");
}
}
// ==== Creator (Factory) ====
abstract class ShapeFactory {
public abstract Shape createShape(); // Factory Method
}
// ==== Concrete Creators ====
class CircleFactory extends ShapeFactory {
public Shape createShape() {
return new Circle();
}
}
class SquareFactory extends ShapeFactory {
public Shape createShape() {
return new Square();
}
}
Prototype(原型)
Creates a new object from an existing object
public class Main {
public static void main(String[] args) {
Circle originalCircle = new Circle(5);
Circle copiedCircle = (Circle) originalCircle.clone();
originalCircle.draw();
copiedCircle.draw();
System.out.println("Original == Copy? " + (originalCircle == copiedCircle));
}
}
// ==== Prototype Interface ====
interface Shape extends Cloneable {
Shape clone();
void draw();
}
// ==== Concrete Prototype: Circle ====
class Circle implements Shape {
private int radius;
public Circle(int radius) {
this.radius = radius;
}
public void draw() {
System.out.println("Drawing Circle with radius: " + radius);
}
public Shape clone() {
return new Circle(this.radius);
}
}
// ==== Concrete Prototype: Rectangle ====
class Rectangle implements Shape {
private int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public void draw() {
System.out.println("Drawing Rectangle " + width + "x" + height);
}
public Shape clone() {
return new Rectangle(this.width, this.height);
}
}
Singleton(单例)
Ensure only one instance of an object is created
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
instance1.showMessage();
System.out.println("Same instance? " + (instance1 == instance2));
}
}
// ==== Singleton Class ====
class Singleton {
private static Singleton instance;
private Singleton() {
// private constructor to prevent instantiation
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
public void showMessage() {
System.out.println("Hello from Singleton!");
}
}
Structural Design Patterns
Adapter(适配器)
Allows for two incompatible classes to work together by wrapping an interface around one of the existing classes
public class Main {
public static void main(String[] args) {
AudioPlayer player = new AudioPlayer();
player.play("mp3", "song.mp3");
player.play("mp4", "video.mp4");
player.play("vlc", "movie.vlc");
player.play("avi", "clip.avi"); // unsupported
}
}
// ==== Target Interface ====
interface MediaPlayer {
void play(String audioType, String fileName);
}
// ==== Adaptee Interface ====
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
// ==== Concrete Adaptees ====
class VlcPlayer implements AdvancedMediaPlayer {
public void playVlc(String fileName) {
System.out.println("Playing VLC file: " + fileName);
}
public void playMp4(String fileName) {
// do nothing
}
}
class Mp4Player implements AdvancedMediaPlayer {
public void playVlc(String fileName) {
// do nothing
}
public void playMp4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
}
// ==== Adapter ====
class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedPlayer = new Mp4Player();
}
}
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedPlayer.playMp4(fileName);
}
}
}
// ==== Client ====
class AudioPlayer implements MediaPlayer {
MediaAdapter adapter;
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")) {
adapter = new MediaAdapter(audioType);
adapter.play(audioType, fileName);
} else {
System.out.println("Invalid media type: " + audioType);
}
}
}
Bridge(桥接)
Decouples an abstraction so two classes can vary independently.
public class Main {
public static void main(String[] args) {
Renderer vector = new VectorRenderer();
Renderer raster = new RasterRenderer();
Shape circle1 = new Circle(vector, 5);
Shape circle2 = new Circle(raster, 10);
circle1.draw();
circle2.draw();
}
}
// ==== Implementation Hierarchy ====
interface Renderer {
void renderCircle(float radius);
}
class VectorRenderer implements Renderer {
public void renderCircle(float radius) {
System.out.println("Drawing circle with vector renderer, radius: " + radius);
}
}
class RasterRenderer implements Renderer {
public void renderCircle(float radius) {
System.out.println("Drawing circle with raster renderer, radius: " + radius);
}
}
// ==== Abstraction Hierarchy ====
abstract class Shape {
protected Renderer renderer;
public Shape(Renderer renderer) {
this.renderer = renderer;
}
abstract void draw();
}
class Circle extends Shape {
private float radius;
public Circle(Renderer renderer, float radius) {
super(renderer);
this.radius = radius;
}
public void draw() {
renderer.renderCircle(radius);
}
}
Composite(组合)
Takes a group of objects into a single object
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Graphic circle1 = new Circle();
Graphic square1 = new Square();
CompositeGraphic group = new CompositeGraphic();
group.add(circle1);
group.add(square1);
Graphic circle2 = new Circle();
group.add(circle2);
group.draw();
}
}
// ==== Component ====
interface Graphic {
void draw();
}
// ==== Leaf ====
class Circle implements Graphic {
public void draw() {
System.out.println("Drawing Circle");
}
}
class Square implements Graphic {
public void draw() {
System.out.println("Drawing Square");
}
}
// ==== Composite ====
class CompositeGraphic implements Graphic {
private List children = new ArrayList<>();
public void add(Graphic g) {
children.add(g);
}
public void remove(Graphic g) {
children.remove(g);
}
public void draw() {
for (Graphic g : children) {
g.draw();
}
}
}
Decorator(装饰器)
Allows for an object's behavior to be extended dynamically at run time
public class Main {
public static void main(String[] args) {
Text simpleText = new PlainText("Hello");
Text boldText = new BoldDecorator(simpleText);
Text italicText = new ItalicDecorator(boldText);
System.out.println(italicText.render()); // Output: Hello
}
}
// ==== Component Interface ====
interface Text {
String render();
}
// ==== Concrete Component ====
class PlainText implements Text {
private String content;
public PlainText(String content) {
this.content = content;
}
public String render() {
return content;
}
}
// ==== Base Decorator ====
abstract class TextDecorator implements Text {
protected Text inner;
public TextDecorator(Text inner) {
this.inner = inner;
}
}
// ==== Concrete Decorators ====
class BoldDecorator extends TextDecorator {
public BoldDecorator(Text inner) {
super(inner);
}
public String render() {
return "" + inner.render() + "";
}
}
class ItalicDecorator extends TextDecorator {
public ItalicDecorator(Text inner) {
super(inner);
}
public String render() {
return "" + inner.render() + "";
}
}
Facade(外观)
Provides a simple interface to a more complex underlying object
public class Main {
public static void main(String[] args) {
// Subsystem components
Amplifier amp = new Amplifier();
DVDPlayer dvd = new DVDPlayer();
Lights lights = new Lights();
// Facade
HomeTheaterFacade homeTheater = new HomeTheaterFacade(amp, dvd, lights);
homeTheater.watchMovie("Inception");
System.out.println("---");
homeTheater.endMovie();
}
}
// ==== Subsystem Classes ====
class Amplifier {
void on() { System.out.println("Amplifier ON"); }
void off() { System.out.println("Amplifier OFF"); }
}
class DVDPlayer {
void on() { System.out.println("DVD Player ON"); }
void play(String movie) { System.out.println("Playing movie: " + movie); }
void stop() { System.out.println("Stopping DVD"); }
void off() { System.out.println("DVD Player OFF"); }
}
class Lights {
void dim() { System.out.println("Lights dimmed"); }
void on() { System.out.println("Lights ON"); }
}
// ==== Facade ====
class HomeTheaterFacade {
private Amplifier amp;
private DVDPlayer dvd;
private Lights lights;
public HomeTheaterFacade(Amplifier amp, DVDPlayer dvd, Lights lights) {
this.amp = amp;
this.dvd = dvd;
this.lights = lights;
}
public void watchMovie(String movie) {
System.out.println("Get ready to watch a movie...");
lights.dim();
amp.on();
dvd.on();
dvd.play(movie);
}
public void endMovie() {
System.out.println("Shutting movie theater down...");
dvd.stop();
dvd.off();
amp.off();
lights.on();
}
}
Flyweight(享元)
Reduces the cost of complex object models
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
CharacterFactory factory = new CharacterFactory();
TextEditor editor = new TextEditor(factory);
editor.type('a', 1, 1);
editor.type('b', 1, 2);
editor.type('a', 1, 3); // reused flyweight
editor.display();
}
}
// ==== Flyweight Interface ====
interface Character {
void display(int x, int y); // extrinsic state passed at runtime
}
// ==== Concrete Flyweight ====
class ConcreteCharacter implements Character {
private final char symbol; // intrinsic state
public ConcreteCharacter(char symbol) {
this.symbol = symbol;
}
public void display(int x, int y) {
System.out.printf("Character '%c' at (%d, %d)%n", symbol, x, y);
}
}
// ==== Flyweight Factory ====
class CharacterFactory {
private Map pool = new HashMap<>();
public Character get(char symbol) {
return pool.computeIfAbsent(symbol, s -> new ConcreteCharacter(s));
}
}
// ==== Client ====
class TextEditor {
private final CharacterFactory factory;
private final Map characters = new HashMap<>();
private int idCounter = 0;
public TextEditor(CharacterFactory factory) {
this.factory = factory;
}
public void type(char symbol, int x, int y) {
Character sharedChar = factory.get(symbol);
characters.put(idCounter++, new PositionedChar(sharedChar, x, y));
}
public void display() {
for (PositionedChar pc : characters.values()) {
pc.character.display(pc.x, pc.y);
}
}
private static class PositionedChar {
Character character;
int x, y;
PositionedChar(Character character, int x, int y) {
this.character = character;
this.x = x;
this.y = y;
}
}
}
Proxy(代理)
Provides a placeholder interface to an underlying object to control access, reduce cost, or reduce complexity
public class Main {
public static void main(String[] args) {
Image image = new ImageProxy("photo.jpg");
System.out.println("Image created but not loaded.");
System.out.println("Now displaying image...");
image.display(); // triggers actual loading
System.out.println("Displaying again...");
image.display(); // doesn't load again
}
}
// ==== Subject Interface ====
interface Image {
void display();
}
// ==== Real Subject ====
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk(); // expensive operation
}
private void loadFromDisk() {
System.out.println("Loading image from disk: " + filename);
}
public void display() {
System.out.println("Displaying image: " + filename);
}
}
// ==== Proxy ====
class ImageProxy implements Image {
private RealImage realImage;
private String filename;
public ImageProxy(String filename) {
this.filename = filename;
}
public void display() {
if (realImage == null) {
realImage = new RealImage(filename); // lazy loading
}
realImage.display();
}
}
Behavior Design Patterns
Chain of Responsibility(责任链)
Delegates commands to a chain of processing objects
public class Main {
public static void main(String[] args) {
Logger loggerChain = createLoggerChain();
loggerChain.log(Logger.INFO, "This is an info message.");
loggerChain.log(Logger.DEBUG, "This is a debug message.");
loggerChain.log(Logger.ERROR, "This is an error message.");
}
private static Logger createLoggerChain() {
Logger errorLogger = new ErrorLogger();
Logger debugLogger = new DebugLogger();
Logger infoLogger = new InfoLogger();
errorLogger.setNext(debugLogger);
debugLogger.setNext(infoLogger);
return errorLogger; // head of the chain
}
}
// ==== Abstract Handler ====
abstract class Logger {
public static final int INFO = 1;
public static final int DEBUG = 2;
public static final int ERROR = 3;
protected int level;
protected Logger next;
public void setNext(Logger next) {
this.next = next;
}
public void log(int level, String message) {
if (this.level <= level) {
write(message);
}
if (next != null) {
next.log(level, message);
}
}
protected abstract void write(String message);
}
// ==== Concrete Handlers ====
class InfoLogger extends Logger {
public InfoLogger() {
this.level = INFO;
}
protected void write(String message) {
System.out.println("INFO: " + message);
}
}
class DebugLogger extends Logger {
public DebugLogger() {
this.level = DEBUG;
}
protected void write(String message) {
System.out.println("DEBUG: " + message);
}
}
class ErrorLogger extends Logger {
public ErrorLogger() {
this.level = ERROR;
}
protected void write(String message) {
System.out.println("ERROR: " + message);
}
}
Command(命令)
Creates objects which encapsulate actions and parameters
public class Main {
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();
remote.setCommand(lightOff);
remote.pressButton();
}
}
// ==== Command Interface ====
interface Command {
void execute();
}
// ==== Receiver ====
class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
// ==== Concrete Commands ====
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOff();
}
}
// ==== Invoker ====
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
Interpreter(解释器)
Accesses the elements of an object sequentially without exposing its underlying representation
public class Main {
public static void main(String[] args) {
// Expression: true AND false
Expression expr1 = new AndExpression(new TerminalExpression(true), new TerminalExpression(false));
System.out.println("true AND false = " + expr1.interpret());
// Expression: true OR false
Expression expr2 = new OrExpression(new TerminalExpression(true), new TerminalExpression(false));
System.out.println("true OR false = " + expr2.interpret());
}
}
// ==== Expression Interface ====
interface Expression {
boolean interpret();
}
// ==== Terminal Expression ====
class TerminalExpression implements Expression {
private final boolean value;
public TerminalExpression(boolean value) {
this.value = value;
}
public boolean interpret() {
return value;
}
}
// ==== Non-terminal Expressions ====
class AndExpression implements Expression {
private final Expression left;
private final Expression right;
public AndExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean interpret() {
return left.interpret() && right.interpret();
}
}
class OrExpression implements Expression {
private final Expression left;
private final Expression right;
public OrExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean interpret() {
return left.interpret() || right.interpret();
}
}
Iterator(迭代器)
Accesses the elements of an object sequentially without exposing its underlying representation.
public class Main {
public static void main(String[] args) {
NameRepository names = new NameRepository();
Iterator it = names.getIterator();
while (it.hasNext()) {
System.out.println("Name: " + it.next());
}
}
}
// ==== Iterator Interface ====
interface Iterator {
boolean hasNext();
Object next();
}
// ==== Aggregate Interface ====
interface Container {
Iterator getIterator();
}
// ==== Concrete Aggregate ====
class NameRepository implements Container {
private String[] names = {"Alice", "Bob", "Charlie", "Diana"};
public Iterator getIterator() {
return new NameIterator();
}
// ==== Concrete Iterator ====
private class NameIterator implements Iterator {
int index = 0;
public boolean hasNext() {
return index < names.length;
}
public Object next() {
if (this.hasNext()) {
return names[index++];
}
return null;
}
}
}
Mediator(中介者)
Allows loose coupling between classes by being the only class that has detailed knowledge of their methods
public class Main {
public static void main(String[] args) {
ChatRoomMediator chatRoom = new ChatRoom();
User alice = new User("Alice", chatRoom);
User bob = new User("Bob", chatRoom);
User charlie = new User("Charlie", chatRoom);
chatRoom.addUser(alice);
chatRoom.addUser(bob);
chatRoom.addUser(charlie);
alice.send("Hi everyone!");
bob.send("Hey Alice!");
}
}
// ==== Mediator Interface ====
interface ChatRoomMediator {
void sendMessage(String message, User sender);
void addUser(User user);
}
// ==== Concrete Mediator ====
class ChatRoom implements ChatRoomMediator {
private List users = new ArrayList<>();
public void addUser(User user) {
users.add(user);
}
public void sendMessage(String message, User sender) {
for (User u : users) {
if (u != sender) {
u.receive(message, sender.getName());
}
}
}
}
// ==== Colleague ====
class User {
private String name;
private ChatRoomMediator mediator;
public User(String name, ChatRoomMediator mediator) {
this.name = name;
this.mediator = mediator;
}
public String getName() {
return name;
}
public void send(String message) {
System.out.println(name + " sends: " + message);
mediator.sendMessage(message, this);
}
public void receive(String message, String senderName) {
System.out.println(name + " receives from " + senderName + ": " + message);
}
}
Memento(备忘录)
Provides the ability to restore an object to its previous state
public class Main {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
editor.setText("Version 1");
editor.save(); // Save state
editor.setText("Version 2");
editor.save(); // Save state
editor.setText("Version 3");
System.out.println("Current: " + editor.getText());
editor.undo();
System.out.println("After undo: " + editor.getText());
editor.undo();
System.out.println("After second undo: " + editor.getText());
}
}
// ==== Originator ====
class TextEditor {
private String text;
private final History history = new History();
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void save() {
history.addMemento(new Memento(text));
}
public void undo() {
Memento m = history.getLastMemento();
if (m != null) {
text = m.getState();
}
}
}
// ==== Memento ====
class Memento {
private final String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// ==== Caretaker ====
class History {
private final java.util.Stack mementos = new java.util.Stack<>();
public void addMemento(Memento m) {
mementos.push(m);
}
public Memento getLastMemento() {
if (!mementos.isEmpty()) {
return mementos.pop();
}
return null;
}
}
Observer(观察者)
Is a publish/subscribe pattern which allows a number of observer objects to see an event
public class Main {
public static void main(String[] args) {
NewsAgency agency = new NewsAgency();
Subscriber alice = new Subscriber("Alice");
Subscriber bob = new Subscriber("Bob");
agency.addObserver(alice);
agency.addObserver(bob);
agency.setNews("Breaking: Observer pattern in action!");
agency.setNews("Update: Java makes it easy!");
}
}
// ==== Observer Interface ====
interface Observer {
void update(String news);
}
// ==== Concrete Observer ====
class Subscriber implements Observer {
private String name;
public Subscriber(String name) {
this.name = name;
}
public void update(String news) {
System.out.println(name + " received news: " + news);
}
}
// ==== Subject ====
class NewsAgency {
private List observers = new ArrayList<>();
private String news;
public void addObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
observers.remove(o);
}
public void setNews(String news) {
this.news = news;
notifyObservers();
}
private void notifyObservers() {
for (Observer o : observers) {
o.update(news);
}
}
}
State(状态)
Allows an object to alter its behavior when its internal state changes
public class Main {
public static void main(String[] args) {
DeviceContext context = new DeviceContext();
context.pressPowerButton(); // Turning ON...
context.pressPowerButton(); // Turning OFF...
context.pressPowerButton(); // Turning ON...
}
}
// ==== State Interface ====
interface State {
void pressPowerButton(DeviceContext context);
}
// ==== Concrete States ====
class OnState implements State {
public void pressPowerButton(DeviceContext context) {
System.out.println("Turning OFF...");
context.setState(new OffState());
}
}
class OffState implements State {
public void pressPowerButton(DeviceContext context) {
System.out.println("Turning ON...");
context.setState(new OnState());
}
}
// ==== Context ====
class DeviceContext {
private State state;
public DeviceContext() {
state = new OffState(); // default state
}
public void setState(State state) {
this.state = state;
}
public void pressPowerButton() {
state.pressPowerButton(this);
}
}
Strategy(策略)
Allows one of a family of algorithms to be selected on-the-fly at run-time
public class Main {
public static void main(String[] args) {
Context context;
context = new Context(new AddStrategy());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new SubtractStrategy());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new MultiplyStrategy());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
// ==== Strategy Interface ====
interface Strategy {
int doOperation(int a, int b);
}
// ==== Concrete Strategies ====
class AddStrategy implements Strategy {
public int doOperation(int a, int b) {
return a + b;
}
}
class SubtractStrategy implements Strategy {
public int doOperation(int a, int b) {
return a - b;
}
}
class MultiplyStrategy implements Strategy {
public int doOperation(int a, int b) {
return a * b;
}
}
// ==== Context ====
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return strategy.doOperation(a, b);
}
}
Template Method(模版)
Defines the skeleton of an algorithm as an abstract class, allowing its sub-classes to provide concrete behavior
public abstract class AbstractBatchStep {
// Template Method
public final void executeStep() {
beforeStep();
process();
afterStep();
}
protected void beforeStep() {
System.out.println("Default before step logic");
}
protected abstract void process(); // to be implemented by subclass
protected void afterStep() {
System.out.println("Default after step logic");
}
}
public class MyCustomStep extends AbstractBatchStep {
@Override
protected void process() {
System.out.println("Custom step processing logic");
}
}
public class BatchRunner {
public static void main(String[] args) {
AbstractBatchStep step = new MyCustomStep();
step.executeStep(); // Template method pattern in action
}
}
@Bean
public ItemReader myReader() {
return new ListItemReader<>(List.of("one", "two", "three"));
}
@Bean
public ItemProcessor myProcessor() {
return item -> item.toUpperCase();
}
@Bean
public ItemWriter myWriter() {
return items -> items.forEach(System.out::println);
}
@Bean
public Job myJob(JobBuilderFactory jobBuilders, StepBuilderFactory stepBuilders) {
return jobBuilders.get("myJob")
.start(myStep(stepBuilders))
.build();
}
@Bean
public Step myStep(StepBuilderFactory stepBuilders) {
return stepBuilders.get("myStep")
.chunk(10)
.reader(myReader())
.processor(myProcessor())
.writer(myWriter())
.build();
}
Visitor(访问者)
Separates an algorithm from an object structure by moving the hierarchy of methods into one object
public class Main {
public static void main(String[] args) {
DocumentElement[] elements = {
new Paragraph("Hello, world!"),
new Image("diagram.png")
};
DocumentVisitor renderVisitor = new RenderVisitor();
DocumentVisitor exportVisitor = new ExportVisitor();
System.out.println("Rendering:");
for (DocumentElement element : elements) {
element.accept(renderVisitor);
}
System.out.println("\nExporting:");
for (DocumentElement element : elements) {
element.accept(exportVisitor);
}
}
}
// ==== Visitor Interface ====
interface DocumentVisitor {
void visit(Paragraph paragraph);
void visit(Image image);
}
// ==== Element Interface ====
interface DocumentElement {
void accept(DocumentVisitor visitor);
}
// ==== Concrete Elements ====
class Paragraph implements DocumentElement {
String text;
public Paragraph(String text) {
this.text = text;
}
public void accept(DocumentVisitor visitor) {
visitor.visit(this);
}
}
class Image implements DocumentElement {
String fileName;
public Image(String fileName) {
this.fileName = fileName;
}
public void accept(DocumentVisitor visitor) {
visitor.visit(this);
}
}
// ==== Concrete Visitors ====
class RenderVisitor implements DocumentVisitor {
public void visit(Paragraph paragraph) {
System.out.println("Rendering paragraph: " + paragraph.text);
}
public void visit(Image image) {
System.out.println("Rendering image: " + image.fileName);
}
}
class ExportVisitor implements DocumentVisitor {
public void visit(Paragraph paragraph) {
System.out.println("Exporting paragraph to PDF: " + paragraph.text);
}
public void visit(Image image) {
System.out.println("Exporting image to PDF: " + image.fileName);
}
}
Comments
Post a Comment