在软件开发中,设计模式是重要的指导原则,它们提供了解决特定问题的可重用方案。Java作为一种强大的编程语言,广泛应用了许多设计模式。让我们深入探讨几种常见的设计模式,并展示它们在实际Java应用中的用例。
1. 单例模式 (Singleton Pattern)
单例模式确保一个类只有一个实例,并提供一个全局访问点。
public class Singleton {
private static Singleton instance;
private Singleton() {} // 私有构造函数
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// 在实际应用中的使用:
public class SingletonApp {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
// 使用obj进行操作
}
}
2. 工厂模式 (Factory Pattern)
工厂模式用于创建对象,但将具体创建的逻辑封装在一个单独的类中。
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 ShapeFactory {
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
} else if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}
// 在实际应用中的使用:
public class FactoryPatternApp {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
Shape circle = shapeFactory.getShape("CIRCLE");
circle.draw(); // 输出:画一个圆形
Shape rectangle = shapeFactory.getShape("RECTANGLE");
rectangle.draw(); // 输出:画一个矩形
}
}
3. 观察者模式 (Observer Pattern)
观察者模式用于对象之间的一对多依赖关系,当一个对象状态改变时,其依赖对象会得到通知并自动更新。
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update();
}
class Subject {
private List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
class BinaryObserver implements Observer {
private Subject subject;
public BinaryObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Binary String: " + Integer.toBinaryString(subject.getState()));
}
}
// 在实际应用中的使用:
public class ObserverPatternApp {
public static void main(String[] args) {
Subject subject = new Subject();
new BinaryObserver(subject);
subject.setState(10); // 输出:Binary String: 1010
}
}
4. 装饰器模式 (Decorator Pattern)
装饰器模式允许向现有对象动态地添加新功能,它是继承的替代方案。
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("画一个矩形");
}
}
abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
public void draw() {
decoratedShape.draw();
}
}
class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape) {
System.out.println("边框颜色:红色");
}
}
// 在实际应用中的使用:
public class DecoratorPatternApp {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape redRectangle = new RedShapeDecorator(new Rectangle());
circle.draw(); // 输出:画一个圆形
redCircle.draw();
// 输出:
// 画一个圆形
// 边框颜色:红色
redRectangle.draw();
// 输出:
// 画一个矩形
// 边框颜色:红色
}
}
5. 策略模式 (Strategy Pattern)
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,使得算法可独立于使用它的客户而变化。
interface Strategy {
int doOperation(int num1, int num2);
}
class OperationAdd implements Strategy {
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
class OperationSubtract implements Strategy {
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
// 在实际应用中的使用:
public class StrategyPatternApp {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
}
}
6. 原型模式 (Prototype Pattern)
原型模式用于创建对象的一种方式,通过复制现有对象来生成新对象,避免了构造函数的执行。
import java.util.HashMap;
import java.util.Map;
abstract class Shape implements Cloneable {
protected String type;
abstract void draw();
public String getType() {
return type;
}
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
class Circle extends Shape {
public Circle() {
type = "Circle";
}
@Override
void draw() {
System.out.println("画一个圆形");
}
}
class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
@Override
void draw() {
System.out.println("画一个矩形");
}
}
class ShapeCache {
private static Map<String, Shape> shapeMap = new HashMap<>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
public static void loadCache() {
Circle circle = new Circle();
circle.draw();
shapeMap.put(circle.getType(), circle);
Rectangle rectangle = new Rectangle();
rectangle.draw();
shapeMap.put(rectangle.getType(), rectangle);
}
}
// 在实际应用中的使用:
public class PrototypePatternApp {
public static void main(String[] args) {
ShapeCache.loadCache();
Shape clonedShape1 = ShapeCache.getShape("Circle");
System.out.println("Shape : " + clonedShape1.getType());
Shape clonedShape2 = ShapeCache.getShape("Rectangle");
System.out.println("Shape : " + clonedShape2.getType());
}
}
7. 适配器模式 (Adapter Pattern)
适配器模式允许接口不兼容的类能够一起工作,将一个类的接口转换成客户希望的另一个接口。
interface MediaPlayer {
void play(String audioType, String fileName);
}
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
@Override
public void playMp4(String fileName) {
// do nothing
}
}
class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// do nothing
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
}
class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file. Name: " + fileName);
} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media. " + audioType + " format not supported");
}
}
}
// 在实际应用中的使用:
public class AdapterPatternApp {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
8. 桥接模式 (Bridge Pattern)
桥接模式将抽象部分与它的实现部分分离,以便两者能够独立地变化。
interface DrawAPI {
void drawCircle(int radius, int x, int y);
}
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 + "]");
}
}
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 + "]");
}
}
abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI) {
this.drawAPI = drawAPI;
}
public abstract void draw();
}
class Circle extends Shape {
private int x, y, radius;
public Circle(int x, int y, int radius, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
public void draw() {
drawAPI.drawCircle(radius, x, y);
}
}
// 在实际应用中的使用:
public class BridgePatternApp {
public static void main(String[] args) {
Shape redCircle = new Circle(100, 100, 10, new RedCircle());
Shape greenCircle = new Circle(100, 100, 10, new GreenCircle());
redCircle.draw();
greenCircle.draw();
}
}
9. 建造者模式 (Builder Pattern)
建造者模式用于构建复杂对象,将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
class Meal {
private String drink;
private String mainCourse;
private String side;
public void setDrink(String drink) {
this.drink = drink;
}
public void setMainCourse(String mainCourse) {
this.mainCourse = mainCourse;
}
public void setSide(String side) {
this.side = side;
}
public void showItems() {
System.out.println("Drink: " + drink);
System.out.println("Main Course: " + mainCourse);
System.out.println("Side: " + side);
}
}
interface MealBuilder {
void buildDrink();
void buildMainCourse();
void buildSide();
Meal getMeal();
}
class VegMealBuilder implements MealBuilder {
private Meal meal = new Meal();
public void buildDrink() {
meal.setDrink("Water");
}
public void buildMainCourse() {
meal.setMainCourse("Salad");
}
public void buildSide() {
meal.setSide("Bread");
}
public Meal getMeal() {
return meal;
}
}
class MealDirector {
public Meal createMeal(MealBuilder mealBuilder) {
mealBuilder.buildDrink();
mealBuilder.buildMainCourse();
mealBuilder.buildSide();
return mealBuilder.getMeal();
}
}
// 在实际应用中的使用:
public class BuilderPatternApp {
public static void main(String[] args) {
MealBuilder vegMealBuilder = new VegMealBuilder();
MealDirector mealDirector = new MealDirector();
Meal meal = mealDirector.createMeal(vegMealBuilder);
meal.showItems();
}
}