Java最常用的几种设计模式详解及适用业务场景

Java最常用的几种设计模式详解及适用业务场景

Java设计模式详解及适用业务场景

在软件开发中,设计模式是解决常见问题的最佳实践。通过采用这些设计模式,我们可以提高代码的可维护性、可读性和可扩展性。本文将介绍几种常见的Java设计模式,并结合具体代码示例,探讨它们适用的业务场景。

1. 单例模式(Singleton Pattern)

定义:确保一个类只有一个实例,并提供一个全局访问点。优点:节约系统资源,提高系统性能;严格控制访问权限。应用场景:数据库连接池、日志记录器、配置管理器等需要全局唯一实例的场景。

代码示例:

public class Singleton {

// 创建一个静态的实例变量,并初始化为null

private static Singleton instance = null;

// 私有构造函数,防止外部实例化

private Singleton() {}

// 提供一个公共的静态方法,用于返回唯一的实例

public static Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

// 其他方法

public void showMessage() {

System.out.println("Hello World!");

}

}

2. 工厂模式(Factory Pattern)

定义:通过定义创建对象的接口,让子类决定实例化哪一个类。分类:包括简单工厂模式、工厂方法模式和抽象工厂模式。优点:增加程序的灵活性和可维护性;解耦对象的创建和使用

代码示例:

// 产品接口

interface Shape {

void draw();

}

// 具体产品类

class Circle implements Shape {

public void draw() {

System.out.println("Inside Circle::draw() method.");

}

}

class Rectangle implements Shape {

public void draw() {

System.out.println("Inside Rectangle::draw() method.");

}

}

// 工厂类

class ShapeFactory {

// 使用getShape方法获取对象

public Shape getShape(String shapeType) {

if (shapeType == null) {

return null;

}

if (shapeType.equalsIgnoreCase("CIRCLE")) {

return new Circle();

} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {

return new Rectangle();

}

return null;

}

}

适用业务场景:

对象创建复杂:如涉及大量资源分配、复杂初始化逻辑或需要依赖注入的对象。解耦对象创建与具体实现:客户端代码无需知道对象如何创建,只需知道如何使用。

3. 观察者模式(Observer Pattern)

定义:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,所有依赖它的观察者对象都会收到通知并自动更新。优点:实现松耦合,提高系统可维护性;支持广播通信。应用场景:GUI事件处理、发布-订阅系统、消息推送等。

代码示例:

import java.util.ArrayList;

import java.util.List;

// 主题接口

interface Subject {

void registerObserver(Observer o);

void removeObserver(Observer o);

void notifyObservers();

}

// 具体主题类

class ConcreteSubject implements Subject {

private List observers;

private int state;

public ConcreteSubject() {

observers = new ArrayList<>();

}

public void registerObserver(Observer o) {

observers.add(o);

}

public void removeObserver(Observer o) {

observers.remove(o);

}

public void notifyObservers() {

for (Observer observer : observers) {

observer.update(state);

}

}

public int getState() {

return state;

}

public void setState(int state) {

this.state = state;

notifyObservers();

}

}

// 观察者接口

interface Observer {

void update(int state);

}

// 具体观察者类

class ConcreteObserver implements Observer {

private String name;

public ConcreteObserver(String name) {

this.name = name;

}

public void update(int state) {

System.out.println("Observer " + name + " received state " + state);

}

}

适用业务场景:

事件驱动系统:如GUI框架、消息队列系统等,当一个对象的状态改变时需要通知其他对象。实现发布/订阅模型:在内容管理系统、社交媒体平台等,用户可以订阅感兴趣的内容,并在内容更新时收到通知。

4. 策略模式(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 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);

}

}

适用业务场景:

算法选择:在需要根据不同条件选择不同的算法或行为时,如排序算法的选择。多条件分支处理:避免大量if-else语句,提高代码的可维护性和可读性。

5、适配器模式(Adapter Pattern)

定义:将一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的类可以一起工作。优点:提高代码的复用性;符合开闭原则。应用场景:需要使用现有的类,但类的接口不符合系统要求时。

代码示例:

// 目标接口

public interface NewInterface {

void newMethod();

}

// 源接口(老接口)

public class OldClass {

public void oldMethod() {

System.out.println("OldClass: 调用旧方法");

}

}

// 适配器类

public class Adapter implements NewInterface {

private final OldClass oldClass;

public Adapter(OldClass oldClass) {

this.oldClass = oldClass;

}

@Override

public void newMethod() {

oldClass.oldMethod();

}

}

// 测试类

public class AdapterExample {

public static void main(String[] args) {

OldClass oldClass = new OldClass();

NewInterface adapter = new Adapter(oldClass);

adapter.newMethod(); // 调用新接口的方法,但实际调用的是旧接口的方法

}

}

6、装饰器模式(Decorator Pattern)

定义:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。优点:提高代码的复用性和扩展性;符合开闭原则。应用场景:需要在不修改原有代码的情况下,为对象动态添加功能时。

代码示例:

装饰器模式允许向一个现有的对象添加新的功能,同时不改变其结构。

// 组件接口

interface Component {

void operation();

}

// 具体组件

class ConcreteComponent implements Component {

@Override

public void operation() {

System.out.println("执行具体组件的操作");

}

}

// 装饰器抽象类

abstract class Decorator implements Component {

protected Component component;

public Decorator(Component component) {

this.component = component;

}

@Override

public void operation() {

component.operation();

}

}

// 具体装饰器 A

class ConcreteDecoratorA extends Decorator {

public ConcreteDecoratorA(Component component) {

super(component);

}

@Override

public void operation() {

super.operation();

System.out.println("执行具体装饰器 A 的额外操作");

}

}

// 具体装饰器 B

class ConcreteDecoratorB extends Decorator {

public ConcreteDecoratorB(Component component) {

super(component);

}

@Override

public void operation() {

super.operation();

System.out.println("执行具体装饰器 B 的额外操作");

}

}

// 测试类

public class DecoratorPatternExample {

public static void main(String[] args) {

Component component = new ConcreteComponent();

Component decoratedComponentA = new ConcreteDecoratorA(component);

Component decoratedComponentB = new ConcreteDecoratorB(decoratedComponentA);

decoratedComponentB.operation();

}

}

7、代理模式(Proxy Pattern)

定义:为其他对象提供一种代理以控制对这个对象的访问。优点:实现远程代理、虚拟代理、保护代理等功能;隐藏对象的创建细节。应用场景:需要对访问进行控制、延迟加载、日志记录等场景。

代码示例:

代理模式为其他对象提供一种代理以控制对这个对象的访问。

// 接口

interface UserService {

void performAction();

}

// 实际服务类

class RealUserService implements UserService {

@Override

public void performAction() {

System.out.println("执行实际操作");

}

}

// 代理类

class UserServiceProxy implements UserService {

private UserService realUserService;

private String userRole;

public UserServiceProxy(String userRole) {

this.userRole = userRole;

}

@Override

public void performAction() {

if ("admin".equals(userRole)) {

if (realUserService == null) {

realUserService = new RealUserService();

}

realUserService.performAction();

} else {

System.out.println("您没有足够的权限执行此操作");

}

}

public static void main(String[] args) {

// 以管理员身份调用

UserService adminProxy = new UserServiceProxy("admin");

adminProxy.performAction();

// 以普通用户身份调用

UserService normalUserProxy = new UserServiceProxy("normal");

normalUserProxy.performAction();

}

}

8、 外观模式(Facade Pattern)

定义:为子系统中的一组接口提供一个统一的接口,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。优点:简化接口,降低客户端与子系统之间的耦合度;提高系统的易用性。应用场景:需要将复杂子系统的接口简化时。

代码示例:

// 子系统A

class SubsystemA {

public void operationA() {

System.out.println("子系统A");

}

}

// 子系统B

class SubsystemB {

public void operationB() {

System.out.println("子系统B");

}

}

// 外观类

class Facade {

private SubsystemA subsystemA;

private SubsystemB subsystemB;

public Facade() {

this.subsystemA = new SubsystemA();

this.subsystemB = new SubsystemB();

}

public void operation() {

subsystemA.operationA();

subsystemB.operationB();

}

}

// 测试代码

public class FacadePatternExample {

public static void main(String[] args) {

Facade facade = new Facade();

facade.operation();

}

}

9、 模板方法模式(Template Method Pattern)

定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中实现。优点:实现代码复用,提高系统灵活性;符合开闭原则。应用场景:需要在多个子类中实现相同的算法流程,但具体步骤有所差异时。

代码示例:

// 抽象类

abstract class Coffee {

// 模板方法:定义咖啡制作的流程

public final void prepareCoffee() {

boilWater();

brewCoffee();

pourInCup();

addCondiments();

}

// 抽象方法:子类需要实现具体的制作步骤

protected abstract void brewCoffee();

// 钩子方法:子类可以选择覆盖或使用默认实现

protected void addCondiments() {

System.out.println("Adding condiments");

}

// 具体方法:共用的步骤

private void boilWater() {

System.out.println("Boiling water");

}

private void pourInCup() {

System.out.println("Pouring into cup");

}

}

// 具体子类:美式咖啡

class AmericanCoffee extends Coffee {

@Override

protected void brewCoffee() {

System.out.println("Brewing American coffee");

}

}

// 具体子类:拿铁咖啡

class LatteCoffee extends Coffee {

@Override

protected void brewCoffee() {

System.out.println("Brewing Latte coffee");

}

@Override

protected void addCondiments() {

System.out.println("Adding milk and foam");

}

}

// 客户端代码

public class Client {

public static void main(String[] args) {

Coffee coffee = new AmericanCoffee();

coffee.prepareCoffee();

coffee = new LatteCoffee();

coffee.prepareCoffee();

}

}

适用业务场景

支付处理系统:支付流程通常包括验证、记账和通知等步骤,但具体的实现可能因支付方式而异。模板方法模式允许定义一个算法的骨架,同时留下一些扩展点供子类实现。图形界面应用程序:在GUI应用程序中,事件处理流程可能相似,但具体的响应可能不同。通过模板方法模式,可以定义一个事件处理的骨架,并在子类中实现具体的响应。产品组装线:在制造工厂中,不同的产品可能需要不同的组装步骤,但总体流程是一致的。模板方法模式可以定义组装的骨架,并在子类中实现具体的组装步骤。

相关推荐

生肖查询
365batapp

生肖查询

📅 10-08 👁️ 9527
犮 - 碧蓝航线WIKI
365网站打不开了

犮 - 碧蓝航线WIKI

📅 07-09 👁️ 645
都暻秀도경수|Doh Kyungsoo|D.O
365batapp

都暻秀도경수|Doh Kyungsoo|D.O

📅 07-05 👁️ 5461
Java 对象和类
365bet资讯

Java 对象和类

📅 08-19 👁️ 8747
长虹的55寸智能电视哪款比较好 长虹电视比较热门的55Q3T、55U1和新款55Q5N,价格相差有点大,但参数配置上好像也太多的差别?
回顾10位最佳右后卫,他们激励着一代又一代跟随他们足迹的后浪们