Java常用设计模式简介与实践
发布时间: 2024-02-01 10:08:50 阅读量: 15 订阅数: 12
# 1. 设计模式概述
设计模式是软件工程中经验丰富的开发人员们对各类常见问题的解决方案的总结和提炼。它是一种反复出现的问题,在给定环境下的解决方案。在软件开发过程中,设计模式是解决特定类型问题的最佳实践。在本章中,我们将介绍设计模式的概念、分类和重要性。
## 1.1 设计模式的概念
设计模式是针对特定问题的解决方案,是软件开发过程中对经验的总结与提炼。它提供了一套经过验证的方法来解决软件开发中的常见问题。设计模式并不是可以直接转化为源代码的具体设计。它是一种面向对象设计的经验总结,包含了被反复使用的成功设计的可复用方案。
## 1.2 设计模式的分类
设计模式可分为三大类:创建型模式、结构型模式和行为型模式。其中,创建型模式关注对象的实例化过程,结构型模式关注类和对象的组合,行为型模式关注对象之间的交互和职责分配。
## 1.3 设计模式的重要性
设计模式的重要性体现在以下几个方面:
- 提供了可复用的解决方案:设计模式提供了经过验证的、通用的解决方案,可以在不同的项目中重复使用。
- 促进了代码的可读性和可维护性:设计模式使代码结构更清晰,易于理解和维护。
- 推动了行业最佳实践:设计模式是经验的总结,代表了行业最佳实践,可以帮助开发者避免一些常见的错误。
在接下来的章节中,我们将对不同类型的设计模式进行详细介绍,并结合实际的代码案例进行解析和实践。
# 2. 创建型设计模式
#### 2.1 工厂模式
工厂模式是一种创建型设计模式,旨在通过将对象的创建代码封装在一个单独的类中来解决对象的创建问题。
##### 场景
假设我们正在开发一个汽车销售系统,根据客户的需求创建不同类型的汽车对象。我们可以使用工厂模式来解决这个问题。首先,我们定义一个抽象的汽车类Car:
```java
public abstract class Car {
public abstract void assemble();
}
```
然后,我们定义不同类型的汽车类:
```java
public class SedanCar extends Car {
@Override
public void assemble() {
System.out.println("Assembling a Sedan Car.");
}
}
public class SuvCar extends Car {
@Override
public void assemble() {
System.out.println("Assembling an SUV Car.");
}
}
```
接下来,我们创建一个工厂类CarFactory,用于根据客户需求创建不同类型的汽车对象:
```java
public class CarFactory {
public Car createCar(String type) {
if (type.equalsIgnoreCase("sedan")) {
return new SedanCar();
} else if (type.equalsIgnoreCase("suv")) {
return new SuvCar();
}
return null;
}
}
```
##### 代码总结
在工厂模式中,我们将对象的创建过程封装在工厂类中,客户端只需要通过工厂类来创建对象。这样可以减少客户端与具体对象之间的耦合,提高了代码的灵活性和可维护性。
##### 结果说明
我们可以通过以下代码来测试工厂模式的使用:
```java
public class Main {
public static void main(String[] args) {
CarFactory carFactory = new CarFactory();
Car sedanCar = carFactory.createCar("sedan");
sedanCar.assemble(); // Output: "Assembling a Sedan Car."
Car suvCar = carFactory.createCar("suv");
suvCar.assemble(); // Output: "Assembling an SUV Car."
}
}
```
运行以上代码,我们可以看到根据客户需求,工厂模式成功创建了不同类型的汽车对象,并调用了相应的方法。
#### 2.2 抽象工厂模式
抽象工厂模式是一种创建型设计模式,旨在提供一个接口,用于创建相关或依赖对象的家族,而无需指定具体类。
##### 场景
假设我们正在开发一个在线购物系统,该系统能够根据客户需求创建不同品牌的商品,例如手机和电视。每个品牌都有对应的手机和电视型号。我们可以使用抽象工厂模式来解决这个问题。首先,我们定义一个抽象的手机类Phone和一个抽象的电视类TV:
```java
public interface Phone {
void call();
}
public interface TV {
void display();
}
```
然后,我们定义具体的手机类和电视类:
```java
public class ApplePhone implements Phone {
@Override
public void call() {
System.out.println("Making a call with an Apple Phone.");
}
}
public class SamsungPhone implements Phone {
@Override
public void call() {
System.out.println("Making a call with a Samsung Phone.");
}
}
public class SonyTV implements TV {
@Override
public void display() {
System.out.println("Displaying on a Sony TV.");
}
}
public class LGTV implements TV {
@Override
public void display() {
System.out.println("Displaying on an LG TV.");
}
}
```
接下来,我们定义抽象工厂类DeviceFactory,用于创建相关品牌的手机和电视:
```java
public interface DeviceFactory {
Phone createPhone();
TV createTV();
}
public class AppleFactory implements DeviceFactory {
@Override
public Phone createPhone() {
return new ApplePhone();
}
@Override
public TV createTV() {
return null;
}
}
public class SamsungFactory implements DeviceFactory {
@Override
public Phone createPhone() {
return new SamsungPhone();
}
@Override
public TV createTV() {
return null;
}
}
public class SonyFactory implements DeviceFactory {
@Override
public Phone createPhone() {
return null;
}
@Override
public TV createTV() {
return new SonyTV();
}
}
public class LGFactory implements DeviceFactory {
@Override
public Phone createPhone() {
return null;
}
@Override
public TV createTV() {
return new LGTV();
}
}
```
##### 代码总结
抽象工厂模式通过使用接口来定义一组相关的产品,由具体的工厂类来创建这些产品。客户端只需调用相应的工厂类的方法,而无需关注具体的产品创建过程。这样可以实现产品家族的统一创建,提高代码的可扩展性。
##### 结果说明
我们可以通过以下代码来测试抽象工厂模式的使用:
```java
public class Main {
public static void main(String[] args) {
DeviceFactory appleFactory = new AppleFactory();
Phone applePhone = appleFactory.createPhone();
applePhone.call(); // Output: "Making a call with an Apple Phone."
DeviceFactory samsungFactory = new SamsungFactory();
Phone samsungPhone = samsungFactory.createPhone();
samsungPhone.call(); // Output: "Making a call with a Samsung Phone."
DeviceFactory sonyFactory = new SonyFactory();
TV sonyTV = sonyFactory.createTV();
sonyTV.display(); // Output: "Displaying on a Sony TV."
DeviceFactory lgFactory = new LGFactory();
TV lgTV = lgFactory.createTV();
lgTV.display(); // Output: "Displaying on an LG TV."
}
}
```
运行以上代码,我们可以看到抽象工厂模式成功创建了不同品牌的手机和电视对象。
# 3. 结构型设计模式
结构型设计模式主要关注如何组合类和对象以获得更大的结构。它涉及到对象的组合,提供了一种优雅地建立对象关系的方法。以下是结构型设计模式的详细介绍:
#### 3.1 适配器模式
适配器模式是一种结构型设计模式,用于使接口不兼容的对象能够相互合作。该模式包括一个适配器类,它允许两个不兼容的接口进行协同工作。适配器模式通常用于旧接口与新接口的适配,或者不同系统之间的适配。
**代码示例:Java实现适配器模式**
```java
// 目标接口
interface Target {
void request();
}
// 需要适配的类
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee specific request");
}
}
// 对象适配器
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
adaptee.specificRequest();
}
}
// 客户端代码
public class AdapterPatternExample {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request();
}
}
```
**代码总结:** 适配器模式通过创建一个适配器来将目标接口转换为客户端所期望的接口,实现了两者的兼容性。
**结果说明:** 在这个示例中,Adaptee的specificRequest方法通过Adapter被适配成了Target的request方法,实现了两个不兼容接口的协同工作。
#### 3.2 装饰者模式
装饰者模式允许向对象动态添加新功能,是一种替代继承的方式。通过将对象封装在装饰者类中,可以在运行时动态地改变对象的行为。这种模式能够在不改变原始对象结构的情况下,对对象进行功能的动态扩展。
**代码示例:Java实现装饰者模式**
```java
// 抽象组件
interface Component {
void operation();
}
// 具体组件
class ConcreteComponent implements Component {
public void operation() {
System.out.println("Concrete Component operation");
}
}
// 抽象装饰者
class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
// 具体装饰者
class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addedBehavior();
}
private void addedBehavior() {
System.out.println("Added Behavior");
}
}
// 客户端代码
public class DecoratorPatternExample {
public static void main(String[] args) {
Component component = new ConcreteComponent();
Component decoratedComponent = new ConcreteDecorator(component);
decoratedComponent.operation();
}
}
```
**代码总结:** 装饰者模式通过在运行时动态地组合对象,实现了向对象添加新功能的能力。
**结果说明:** 在这个示例中,通过ConcreteDecorator动态地给ConcreteComponent添加了新的行为功能,同时保持了原始对象结构的不变性。
#### 3.3 代理模式
代理模式为其他对象提供一种代理以控制对这个对象的访问。代理对象通常在客户端和目标对象之间起到中介的作用,可以起到保护目标对象、提高性能或延迟加载等作用。
**代码示例:Java实现代理模式**
```java
// 抽象主题
interface Subject {
void request();
}
// 真实主题
class RealSubject implements Subject {
public void request() {
System.out.println("Real Subject request");
}
}
// 代理
class Proxy implements Subject {
private RealSubject realSubject;
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
preRequest();
realSubject.request();
postRequest();
}
private void preRequest()
```
0
0