请关注微信公众号:拾荒的小海螺
博客地址:http://lsk-ww.cn/
1、简述
设计模式(Design Patterns)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它们可以帮助开发者以一种更优雅和高效的方式解决常见的软件设计问题。本文将介绍三种常见的设计模式,并通过Java代码示例展示它们的实际应用。
2、单例模式(Singleton Pattern)
单例模式确保一个类只有一个实例,并提供一个全局访问点。它常用于需要共享资源的场景,比如配置类、日志类等。
2.1 示例代码
public class Singleton {
// 使用volatile关键字确保多线程环境下的可见性
private static volatile Singleton instance;
// 私有化构造方法,防止外部实例化
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
public void showMessage() {
System.out.println("Hello World from Singleton!");
}
}
2.2 使用示例:
public class SingletonDemo {
public static void main(String[] args) {
Singleton singleInstance = Singleton.getInstance();
singleInstance.showMessage();
}
}
3、工厂模式(Factory Pattern)
工厂模式定义一个用于创建对象的接口,但由子类决定实例化哪一个类。它使得类的实例化延迟到子类。
3.1 示例代码:
// 产品接口
interface Shape {
void draw();
}
// 具体产品类
class Circle implements Shape {
public void draw() {
System.out.println("Drawing a Circle");
}
}
class Square implements Shape {
public void draw() {
System.out.println("Drawing a Square");
}
}
// 工厂类
class ShapeFactory {
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
}
3.2 使用示例:
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
// 获取Circle对象并调用draw方法
Shape shape1 = shapeFactory.getShape("CIRCLE");
shape1.draw();
// 获取Square对象并调用draw方法
Shape shape2 = shapeFactory.getShape("SQUARE");
shape2.draw();
}
}
4、观察者模式(Observer Pattern)
观察者模式定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。它常用于实现事件处理系统。
4.1 示例代码:
import java.util.ArrayList;
import java.util.List;
// 观察者接口
interface Observer {
void update(String message);
}
// 被观察者类
class Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// 具体观察者类
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}
4.2 使用示例:
public class ObserverPatternDemo {
public static void main(String[] args) {
Subject subject = new Subject();
Observer observer1 = new ConcreteObserver("Observer 1");
Observer observer2 = new ConcreteObserver("Observer 2");
subject.attach(observer1);
subject.attach(observer2);
subject.notifyObservers("Hello Observers!");
}
}
5、策略模式(Strategy Pattern)
策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以互换。策略模式让算法独立于使用它的客户而独立变化。
5.1 示例代码:
// 策略接口
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 OperationMultiply 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);
}
}
5.2 使用示例:
public class StrategyPatternDemo {
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));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
6、适配器模式(Adapter Pattern)
适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。它通过将一个类的接口转换成客户希望的另一个接口来实现。
6.1 示例代码:
// 目标接口
interface MediaPlayer {
void play(String audioType, String fileName);
}
// 被适配的接口
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
// 具体的被适配类
class VlcPlayer implements AdvancedMediaPlayer {
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
public void playMp4(String fileName) {
// 什么也不做
}
}
class Mp4Player implements AdvancedMediaPlayer {
public void playVlc(String fileName) {
// 什么也不做
}
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();
}
}
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;
public void play(String audioType, String fileName) {
// 播放mp3音乐文件的内置支持
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file. Name: " + fileName);
}
// mediaAdapter 提供播放其他文件格式的支持
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");
}
}
}
6.2 使用示例:
public class AdapterPatternDemo {
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");
}
}
7、装饰器模式(Decorator Pattern)
装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。它是作为现有的类的一个包装。
7.1 示例代码:
// 组件接口
interface Shape {
void draw();
}
// 具体组件类
class Rectangle implements Shape {
public void draw() {
System.out.println("Shape: Rectangle");
}
}
class Circle implements Shape {
public void draw() {
System.out.println("Shape: Circle");
}
}
// 装饰器抽象类
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("Border Color: Red");
}
}
7.2 使用示例:
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle with red border");
redCircle.draw();
System.out.println("\nRectangle with red border");
redRectangle.draw();
}
}
8、总结
设计模式为我们提供了应对常见软件设计问题的解决方案。在Java中,除了单例模式、工厂模式、观察者模式,我们还介绍了策略模式、适配器模式和装饰器模式。通过合理使用这些设计模式,可以让我们的代码更加简洁、灵活和可维护。希望本文能够帮助你更好地理解和应用设计模式,提高编程效率和代码质量。