您好,登录后才能下订单哦!
设计模式是软件开发中经过验证的解决方案,用于解决常见的设计问题。它们提供了一种标准化的方式来组织和设计代码,使得代码更易于理解、维护和扩展。Java作为一种广泛使用的编程语言,设计模式在其开发中扮演着重要的角色。本文将详细介绍Java设计模式的原则、分类、常见模式及其应用场景。
设计模式的基本原则是指导设计模式创建和应用的核心思想。这些原则帮助开发者编写出高质量、可维护和可扩展的代码。
单一职责原则(Single Responsibility Principle, SRP)指出,一个类应该只有一个引起它变化的原因。换句话说,一个类应该只负责一项职责。这有助于降低类的复杂性,提高代码的可读性和可维护性。
示例:
class User {
private String name;
private String email;
// 构造函数、getter和setter方法
public void saveUser() {
// 保存用户信息到数据库
}
public void sendEmail() {
// 发送电子邮件
}
}
在上面的示例中,User
类负责保存用户信息和发送电子邮件,这违反了单一职责原则。更好的做法是将这两个职责分离到不同的类中:
class User {
private String name;
private String email;
// 构造函数、getter和setter方法
}
class UserRepository {
public void saveUser(User user) {
// 保存用户信息到数据库
}
}
class EmailService {
public void sendEmail(User user) {
// 发送电子邮件
}
}
开闭原则(Open/Closed Principle, OCP)指出,软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着应该通过添加新代码来扩展系统的功能,而不是修改现有的代码。
示例:
class Rectangle {
private double width;
private double height;
// 构造函数、getter和setter方法
public double area() {
return width * height;
}
}
class Circle {
private double radius;
// 构造函数、getter和setter方法
public double area() {
return Math.PI * radius * radius;
}
}
class AreaCalculator {
public double calculateArea(Object shape) {
if (shape instanceof Rectangle) {
return ((Rectangle) shape).area();
} else if (shape instanceof Circle) {
return ((Circle) shape).area();
}
throw new IllegalArgumentException("Unknown shape");
}
}
在上面的示例中,AreaCalculator
类的calculateArea
方法需要根据不同的形状类型进行判断,这违反了开闭原则。更好的做法是使用多态:
interface Shape {
double area();
}
class Rectangle implements Shape {
private double width;
private double height;
// 构造函数、getter和setter方法
@Override
public double area() {
return width * height;
}
}
class Circle implements Shape {
private double radius;
// 构造函数、getter和setter方法
@Override
public double area() {
return Math.PI * radius * radius;
}
}
class AreaCalculator {
public double calculateArea(Shape shape) {
return shape.area();
}
}
里氏替换原则(Liskov Substitution Principle, LSP)指出,子类应该能够替换其父类并且不会影响程序的正确性。这意味着子类应该遵循父类的行为规范,不能改变父类的行为。
示例:
class Bird {
public void fly() {
System.out.println("Flying");
}
}
class Ostrich extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("Ostriches can't fly");
}
}
在上面的示例中,Ostrich
类继承了Bird
类,但它不能飞行,这违反了里氏替换原则。更好的做法是将fly
方法从Bird
类中分离出来:
class Bird {
// 其他方法
}
class FlyingBird extends Bird {
public void fly() {
System.out.println("Flying");
}
}
class Ostrich extends Bird {
// 其他方法
}
接口隔离原则(Interface Segregation Principle, ISP)指出,客户端不应该依赖于它们不需要的接口。这意味着应该将大的接口拆分成更小、更具体的接口,以便客户端只需实现它们所需的方法。
示例:
interface Worker {
void work();
void eat();
}
class HumanWorker implements Worker {
@Override
public void work() {
System.out.println("Working");
}
@Override
public void eat() {
System.out.println("Eating");
}
}
class RobotWorker implements Worker {
@Override
public void work() {
System.out.println("Working");
}
@Override
public void eat() {
throw new UnsupportedOperationException("Robots don't eat");
}
}
在上面的示例中,RobotWorker
类不需要实现eat
方法,这违反了接口隔离原则。更好的做法是将Worker
接口拆分成两个更小的接口:
interface Workable {
void work();
}
interface Eatable {
void eat();
}
class HumanWorker implements Workable, Eatable {
@Override
public void work() {
System.out.println("Working");
}
@Override
public void eat() {
System.out.println("Eating");
}
}
class RobotWorker implements Workable {
@Override
public void work() {
System.out.println("Working");
}
}
依赖倒置原则(Dependency Inversion Principle, DIP)指出,高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。这意味着应该通过接口或抽象类来定义依赖关系,而不是直接依赖于具体的实现。
示例:
class LightBulb {
public void turnOn() {
System.out.println("LightBulb: On");
}
public void turnOff() {
System.out.println("LightBulb: Off");
}
}
class Switch {
private LightBulb bulb;
public Switch(LightBulb bulb) {
this.bulb = bulb;
}
public void operate() {
bulb.turnOn();
}
}
在上面的示例中,Switch
类直接依赖于LightBulb
类,这违反了依赖倒置原则。更好的做法是通过接口来定义依赖关系:
interface Switchable {
void turnOn();
void turnOff();
}
class LightBulb implements Switchable {
@Override
public void turnOn() {
System.out.println("LightBulb: On");
}
@Override
public void turnOff() {
System.out.println("LightBulb: Off");
}
}
class Switch {
private Switchable device;
public Switch(Switchable device) {
this.device = device;
}
public void operate() {
device.turnOn();
}
}
设计模式通常分为三大类:创建型模式、结构型模式和行为型模式。每一类模式都有其特定的用途和应用场景。
创建型模式关注对象的创建过程,旨在将对象的创建与使用分离,使得系统更加灵活和可扩展。常见的创建型模式包括:
结构型模式关注类和对象的组合,旨在通过组合来形成更大的结构,使得系统更加灵活和可扩展。常见的结构型模式包括:
行为型模式关注对象之间的交互和职责分配,旨在使对象之间的交互更加灵活和可扩展。常见的行为型模式包括:
单例模式确保一个类只有一个实例,并提供一个全局访问点。它通常用于控制资源的访问,例如数据库连接或线程池。
示例:
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
工厂模式定义了一个创建对象的接口,但由子类决定实例化哪个类。它将对象的创建与使用分离,使得系统更加灵活。
示例:
interface Product {
void use();
}
class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
class Factory {
public Product createProduct(String type) {
if (type.equals("A")) {
return new ConcreteProductA();
} else if (type.equals("B")) {
return new ConcreteProductB();
}
throw new IllegalArgumentException("Unknown product type");
}
}
抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。它通常用于创建一组相关的对象。
示例:
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
建造者模式将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。它通常用于创建复杂的对象。
示例:
class Product {
private String partA;
private String partB;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
@Override
public String toString() {
return "Product [partA=" + partA + ", partB=" + partB + "]";
}
}
class Builder {
private Product product = new Product();
public void buildPartA(String partA) {
product.setPartA(partA);
}
public void buildPartB(String partB) {
product.setPartB(partB);
}
public Product getResult() {
return product;
}
}
原型模式通过复制现有对象来创建新对象,而不是通过实例化类。它通常用于创建成本较高的对象。
示例:
class Prototype implements Cloneable {
private String field;
public Prototype(String field) {
this.field = field;
}
@Override
public Prototype clone() {
try {
return (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
@Override
public String toString() {
return "Prototype [field=" + field + "]";
}
}
适配器模式将一个类的接口转换成客户端期望的另一个接口,使得原本不兼容的类可以一起工作。它通常用于集成现有的类或库。
示例:
interface Target {
void request();
}
class Adaptee {
public void specificRequest() {
System.out.println("Specific request");
}
}
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
桥接模式将抽象部分与实现部分分离,使它们可以独立变化。它通常用于处理多维度变化的问题。
示例:
interface Implementor {
void operationImpl();
}
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorA operation");
}
}
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorB operation");
}
}
abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
implementor.operationImpl();
}
}
组合模式将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户端可以统一处理单个对象和组合对象。它通常用于处理树形结构的数据。
示例:
interface Component {
void operation();
}
class Leaf implements Component {
@Override
public void operation() {
System.out.println("Leaf operation");
}
}
class Composite implements Component {
private List<Component> children = new ArrayList<>();
public void add(Component component) {
children.add(component);
}
public void remove(Component component) {
children.remove(component);
}
@Override
public void operation() {
for (Component component : children) {
component.operation();
}
}
}
装饰器模式动态地给对象添加额外的职责,而不改变其结构。它通常用于扩展对象的功能。
示例:
interface Component {
void operation();
}
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
System.out.println("ConcreteDecoratorA operation");
}
}
class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
System.out.println("ConcreteDecoratorB operation");
}
}
外观模式为子系统中的一组接口提供了一个统一的接口,使得子系统更易于使用。它通常用于简化复杂系统的接口。
示例:
class SubsystemA {
public void operationA() {
System.out.println("SubsystemA operation");
}
}
class SubsystemB {
public void operationB() {
System.out.println("SubsystemB operation");
}
}
class Facade {
private SubsystemA subsystemA = new SubsystemA();
private SubsystemB subsystemB = new SubsystemB();
public void operation() {
subsystemA.operationA();
subsystemB.operationB();
}
}
享元模式通过共享技术有效地支持大量细粒度的对象。它通常用于减少内存使用和提高性能。
示例:
class Flyweight {
private String intrinsicState;
public Flyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
public void operation(String extrinsicState) {
System.out.println("Intrinsic State: " + intrinsicState);
System.out.println("Extrinsic State: " + extrinsicState);
}
}
class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
flyweights.put(key, new Flyweight(key));
}
return flyweights.get(key);
}
}
代理模式为其他对象提供一个代理以控制对这个对象的访问。它通常用于延迟加载、访问控制、日志记录等。
示例:
”`java interface Subject { void request(); }
class RealSubject implements Subject { @Override
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。