Java设计模式详细讲解
目录
-
设计模式概述
- 1.1 什么是设计模式
- 1.2 设计模式的类型
- 1.3 设计模式的历史与发展
- 1.4 设计模式在软件开发中的重要性
-
创建型模式
- 2.1 单例模式
- 2.2 工厂方法模式
- 2.3 抽象工厂模式
- 2.4 建造者模式
- 2.5 原型模式
-
结构型模式
- 3.1 适配器模式
- 3.2 装饰器模式
- 3.3 代理模式
- 3.4 外观模式
- 3.5 桥接模式
- 3.6 组合模式
- 3.7 享元模式
-
行为型模式
- 4.1 策略模式
- 4.2 模板方法模式
- 4.3 观察者模式
- 4.4 迭代器模式
- 4.5 责任链模式
- 4.6 命令模式
- 4.7 备忘录模式
- 4.8 状态模式
- 4.9 中介者模式
- 4.10 访问者模式
- 4.11 解释器模式
-
设计模式的应用与实践
- 5.1 如何选择合适的设计模式
- 5.2 设计模式在项目中的实际应用
- 5.3 设计模式的最佳实践
- 5.4 设计模式的误用与反模式
-
设计模式的扩展与创新
- 6.1 现代开发中的新模式与新方法
- 6.2 设计模式的组合与变种
- 6.3 设计模式与面向对象设计原则的结合
-
总结
- 7.1 设计模式的学习与深入研究
- 7.2 设计模式在团队开发中的作用
- 7.3 设计模式的未来发展趋势
1. 设计模式概述
1.1 什么是设计模式
设计模式是一套被反复使用的、为特定问题提供解决方案的模板。它们是经过总结和优化的、被业界广泛认可的、用于软件设计中的最佳实践。设计模式并不是具体的代码,而是解决特定设计问题的通用方案。它们帮助开发者避免在编写代码时遇到常见的问题,并且通过模式化的思维提升代码的可读性、可维护性和可扩展性。
1.2 设计模式的类型
设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。
- 创建型模式:关注对象的创建,确保对象的创建过程是高效且灵活的。主要包括单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式。
- 结构型模式:关注类和对象的组合,通过继承或接口来实现结构的灵活性。主要包括适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式和享元模式。
- 行为型模式:关注对象之间的职责分配和通信。主要包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、中介者模式、访问者模式和解释器模式。
1.3 设计模式的历史与发展
设计模式的概念最早由Christopher Alexander在建筑领域提出,后来由Erich Gamma等人引入软件工程。1994年,四位作者(被称为“四人帮”或GoF)出版了《设计模式:可复用面向对象软件的基础》一书,系统性地整理了23种设计模式,从此设计模式成为软件开发中的经典理论之一。
1.4 设计模式在软件开发中的重要性
设计模式通过提供可复用的解决方案,帮助开发者编写更高质量的代码。它们促进了代码的模块化设计,使得软件更加灵活和可维护。同时,设计模式作为一种通用的设计语言,也促进了开发团队之间的沟通和协作。
2. 创建型模式
2.1 单例模式
单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。它通常用于管理全局状态或控制资源访问。
代码示例:
public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
扩展:
- 讨论单例模式的懒汉式、饿汉式、双重检查锁定(DCL)以及枚举单例的实现。
- 分析单例模式的优缺点,尤其是多线程环境下的线程安全问题。
- 提供在实际项目中的应用场景,如数据库连接池、日志系统等。
2.2 工厂方法模式
工厂方法模式(Factory Method Pattern)定义一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
代码示例:
public interface Product {void use();
}public class ConcreteProductA implements Product {public void use() {System.out.println("Using ConcreteProductA");}
}public class ConcreteFactory {public Product createProduct(String type) {if (type.equals("A")) {return new ConcreteProductA();}// 可以扩展其他产品类型的创建逻辑return null;}
}
扩展:
- 讨论工厂方法模式的变体,如静态工厂方法。
- 分析工厂方法模式的优缺点,尤其是当产品种类增加时的扩展性。
- 提供在实际项目中的应用场景,如复杂对象的创建、依赖注入等。
2.3 抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)提供一个接口,用于创建相关或依赖对象的家族,而无需指定具体类。
代码示例:
public interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}public class ConcreteFactory1 implements AbstractFactory {public ProductA createProductA() {return new ProductA1();}public ProductB createProductB() {return new ProductB1();}
}
扩展:
- 讨论抽象工厂模式在构建复杂系统时如何提供一致的产品家族。
- 分析抽象工厂模式的优缺点,尤其是当产品家族扩展时的可维护性。
- 提供在实际项目中的应用场景,如跨平台应用、GUI库等。
2.4 建造者模式
建造者模式(Builder Pattern)将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
代码示例:
public class Product {private String part1;private String part2;public void setPart1(String part1) { this.part1 = part1; }public void setPart2(String part2) { this.part2 = part2; }
}public class ProductBuilder {private Product product = new Product();public ProductBuilder buildPart1(String part1) {product.setPart1(part1);return this;}public ProductBuilder buildPart2(String part2) {product.setPart2(part2);return this;}public Product build() {return product;}
}
扩展:
- 讨论建造者模式如何改善代码的可读性和对象的创建复杂性。
- 分析建造者模式的优缺点,尤其是在构建具有多个可选参数的对象时的优势。
- 提供在实际项目中的应用场景,如创建复杂的配置对象、消息对象等。
2.5 原型模式
原型模式(Prototype Pattern)通过复制现有对象来创建新对象,避免了创建新对象的复杂性和开销。
代码示例:
public class Prototype implements Cloneable {private String state;public Prototype clone() {try {return (Prototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}public void setState(String state) { this.state = state; }public String getState() { return state; }
}
扩展:
- 讨论原型模式在创建复杂对象时如何提高性能和灵活性。
- 分析原型模式的优缺点,尤其是在深拷贝和浅拷贝时的注意事项。
- 提供在实际项目中的应用场景,如对象的快速复制、缓存等。
3. 结构型模式
3.1 适配器模式
适配器模式(Adapter Pattern)将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
代码示例:
public interface Target {void request();
}public class Adaptee {public void specificRequest() {System.out.println("Specific request");}
}public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}public void request() {adaptee.specificRequest();}
}
扩展:
- 讨论类适配器与对象适配器的区别和应用场景。
- 分析适配器模式的优缺点,尤其是在处理遗留代码和第三方库时的灵活性。
- 提供在实际项目中的应用场景,如不同接口的兼容、API集成等。
3.2 装饰器模式
装饰器模式(Decorator Pattern)动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式相比生成子类更为灵活。
代码示例:
public interface Component {void operation();
}public class ConcreteComponent implements Component {public void operation() {System.out.println("ConcreteComponent operation");}
}public class Decorator implements Component {private Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();System.out.println("Decorator added behavior");}
}
扩展:
- 讨论装饰器模式如何替代继承进行功能扩展,避免了子类爆炸。
- 分析装饰器模式的优缺点,尤其是在对象扩展时的灵活性。
- 提供在实际项目中的应用场景,如日志记录、数据校验、动态增强功能等。
3.3 代理模式
代理模式(Proxy Pattern)为其他对象提供一种代理以控制对这个对象的访问。
代码示例:
public interface Subject {void request();
}public class RealSubject implements Subject {public void request() {System.out.println("RealSubject request");}
}public class Proxy implements Subject {private RealSubject realSubject;public Proxy(RealSubject realSubject) {this.realSubject = realSubject;}public void request() {System.out.println("Proxy request");realSubject.request();}
}
扩展:
- 讨论静态代理与动态代理的实现与应用场景。
- 分析代理模式的优缺点,尤其是在安全控制和性能优化中的作用。
- 提供在实际项目中的应用场景,如远程代理、安全代理、虚拟代理等。
3.4 外观模式
外观模式(Facade Pattern)为子系统中的一组接口提供一个一致的界面,使得子系统更容易使用。
代码示例:
public class SubsystemA {public void operationA() {System.out.println("SubsystemA operation");}
}public class SubsystemB {public void operationB() {System.out.println("SubsystemB operation");}
}public class Facade {private SubsystemA subsystemA = new SubsystemA();private SubsystemB subsystemB = new SubsystemB();public void operation() {subsystemA.operationA();subsystemB.operationB();}
}
扩展:
- 讨论外观模式如何简化复杂系统的接口,隐藏子系统的复杂性。
- 分析外观模式的优缺点,尤其是在大型系统中的应用。
- 提供在实际项目中的应用场景,如模块化系统的接口封装、API设计等。
3.5 桥接模式
桥接模式(Bridge Pattern)将抽象部分与它的实现部分分离,使它们都可以独立地变化。
代码示例:
public interface Implementor {void operationImpl();
}public class ConcreteImplementorA implements Implementor {public void operationImpl() {System.out.println("ConcreteImplementorA operation");}
}public abstract class Abstraction {protected Implementor implementor;public Abstraction(Implementor implementor) {this.implementor = implementor;}public abstract void operation();
}public class RefinedAbstraction extends Abstraction {public RefinedAbstraction(Implementor implementor) {super(implementor);}public void operation() {implementor.operationImpl();}
}
扩展:
- 讨论桥接模式如何实现抽象与实现的分离,增强系统的扩展性。
- 分析桥接模式的优缺点,尤其是在应对多维度变化时的优势。
- 提供在实际项目中的应用场景,如跨平台应用、设备驱动程序等。
3.6 组合模式
组合模式(Composite Pattern)将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
代码示例:
public interface Component {void operation();
}public class Leaf implements Component {public void operation() {System.out.println("Leaf operation");}
}public class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component component) {children.add(component);}public void operation() {for (Component child : children) {child.operation();}}
}
扩展:
- 讨论组合模式如何处理树形结构中的复杂关系,使得对象的组合与单个对象操作一致。
- 分析组合模式的优缺点,尤其是在处理递归结构时的灵活性。
- 提供在实际项目中的应用场景,如文件系统、GUI组件树等。
3.7 享元模式
享元模式(Flyweight Pattern)通过共享技术来有效地支持大量细粒度对象的复用。
代码示例:
public class Flyweight {private String intrinsicState;public Flyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("IntrinsicState: " + intrinsicState + ", ExtrinsicState: " + extrinsicState);}
}public 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);}
}
扩展:
- 讨论享元模式如何减少内存占用,提高系统性能,特别是在对象创建开销较大的场景中。
- 分析享元模式的优缺点,尤其是在状态管理和性能优化中的应用。
- 提供在实际项目中的应用场景,如字符处理、对象池等。
4. 行为型模式
4.1 策略模式
策略模式(Strategy Pattern)定义了一系列算法,将每一个算法封装起来,并使它们可以相互替换。策略模式使得算法可以独立于使用它的客户端而变化。
代码示例:
public interface Strategy {void algorithm();
}public class ConcreteStrategyA implements Strategy {public void algorithm() {System.out.println("Algorithm A");}
}public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void executeAlgorithm() {strategy.algorithm();}
}
扩展:
- 讨论策略模式如何通过组合代替继承,减少代码的耦合度。
- 分析策略模式的优缺点,尤其是在动态选择算法时的灵活性。
- 提供在实际项目中的应用场景,如支付方式选择、排序算法等。
4.2 模板方法模式
模板方法模式(Template Method Pattern)定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重新定义算法中的某些步骤。
代码示例:
public abstract class AbstractClass {public final void templateMethod() {primitiveOperation1();primitiveOperation2();}protected abstract void primitiveOperation1();protected abstract void primitiveOperation2();
}public class ConcreteClass extends AbstractClass {protected void primitiveOperation1() {System.out.println("ConcreteClass Operation1");}protected void primitiveOperation2() {System.out.println("ConcreteClass Operation2");}
}
扩展:
- 讨论模板方法模式如何通过控制流程和延迟细节实现代码复用。
- 分析模板方法模式的优缺点,尤其是在构建框架时的应用。
- 提供在实际项目中的应用场景,如算法框架、测试框架等。
4.3 观察者模式
观察者模式(Observer Pattern)定义对象间的一对多依赖关系,使得每当一个对象改变状态时,其相关依赖对象都会收到通知并自动更新。
代码示例:
public interface Observer {void update();
}public class ConcreteObserver implements Observer {public void update() {System.out.println("Observer notified");}
}public class Subject {private List<Observer> observers = new ArrayList<>();public void attach(Observer observer) {observers.add(observer);}public void notifyObservers() {for (Observer observer : observers) {observer.update();}}
}
扩展:
- 讨论观察者模式如何实现对象之间的松耦合和事件驱动机制。
- 分析观察者模式的优缺点,尤其是在处理复杂的依赖关系和通知机制时的优势。
- 提供在实际项目中的应用场景,如事件监听器、发布-订阅系统等。
4.4 迭代器模式
迭代器模式(Iterator Pattern)提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露该对象的内部表示。
代码示例:
public interface Iterator {boolean hasNext();Object next();
}public class ConcreteIterator implements Iterator {private List<Object> list;private int position = 0;public ConcreteIterator(List<Object> list) {this.list = list;}public boolean hasNext() {return position < list.size();}public Object next() {return list.get(position++);}
}
扩展:
- 讨论迭代器模式如何封装集合的遍历逻辑,解耦遍历行为与集合实现。
- 分析迭代器模式的优缺点,尤其是在构建自定义集合类时的应用。
- 提供在实际项目中的应用场景,如集合框架的设计、自定义遍历机制等。
4.5 责任链模式
责任链模式(Chain of Responsibility Pattern)为请求创建一个链式处理对象的机制,当请求沿着这条链传递时,每个处理对象都有机会处理该请求。
代码示例:
public abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(int request);
}public class ConcreteHandler1 extends Handler {public void handleRequest(int request) {if (request < 10) {System.out.println("Handler1 handled request " + request);} else if (successor != null) {successor.handleRequest(request);}}
}
扩展:
- 讨论责任链模式如何通过将处理者链式组织,动态决定请求的处理方式。
- 分析责任链模式的优缺点,尤其是在复杂请求处理流程中的应用。
- 提供在实际项目中的应用场景,如权限验证、事件处理链等。
4.6 命令模式
命令模式(Command Pattern)将请求封装成对象,从而使得可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
代码示例:
public interface Command {void execute();
}public class ConcreteCommand implements Command {private Receiver receiver;public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}public void execute() {receiver.action();}
}public class Receiver {public void action() {System.out.println("Receiver action");}
}
扩展:
- 讨论命令模式如何封装请求,提高系统的可扩展性和灵活性。
- 分析命令模式的优缺点,尤其是在实现可撤销操作和宏命令时的应用。
- 提供在实际项目中的应用场景,如任务调度、事务管理等。
4.7 备忘录模式
备忘录模式(Memento Pattern)在不破坏封装性的前提下,捕获并保存一个对象的内部状态,以便将来恢复到该状态。
代码示例:
public class Memento {private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}
}public class Originator {private String state;public void setState(String state) {this.state = state;}public Memento saveStateToMemento() {return new Memento(state);}public void getStateFromMemento(Memento memento) {state = memento.getState();}
}
扩展:
- 讨论备忘录模式如何通过保存对象状态,实现撤销和恢复功能。
- 分析备忘录模式的优缺点,尤其是在处理对象状态快照时的应用。
- 提供在实际项目中的应用场景,如文本编辑器的撤销功能、游戏存档等。
4.8 状态模式
状态模式(State Pattern)允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
代码示例:
public interface State {void handle();
}public class ConcreteStateA implements State {public void handle() {System.out.println("State A handling");}
}public class Context {private State state;public void setState(State state) {this.state = state;}public void request() {state.handle();}
}
扩展:
- 讨论状态模式如何通过将状态封装为对象,简化复杂状态转换逻辑。
- 分析状态模式的优缺点,尤其是在处理多状态系统时的灵活性。
- 提供在实际项目中的应用场景,如工作流管理、游戏状态机等。
4.9 中介者模式
中介者模式(Mediator Pattern)定义一个中介对象来封装一组对象的交互,使得这些对象不必显式地相互引用,从而使得它们的耦合松散,而且可以独立地改变它们之间的交互。
代码示例:
public interface Mediator {void sendMessage(String message, Colleague colleague);
}public abstract class Colleague {protected Mediator mediator;public Colleague(Mediator mediator) {this.mediator = mediator;}public abstract void receiveMessage(String message);
}public class ConcreteColleague1 extends Colleague {public ConcreteColleague1(Mediator mediator) {super(mediator);}public void receiveMessage(String message) {System.out.println("Colleague1 received: " + message);}
}
扩展:
- 讨论中介者模式如何减少对象间的直接依赖,促进松耦合设计。
- 分析中介者模式的优缺点,尤其是在复杂交互系统中的应用。
- 提供在实际项目中的应用场景,如聊天室、航空管制系统等。
4.10 访问者模式
访问者模式(Visitor Pattern)表示一个作用于某对象结构中的各元素的操作。它使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
代码示例:
public interface Visitor {void visit(Element element);
}public interface Element {void accept(Visitor visitor);
}public class ConcreteElement implements Element {public void accept(Visitor visitor) {visitor.visit(this);}
}
```**扩展**:
- 讨论访问者模式如何将数据结构和操作分离,增加操作的灵活性。
- 分析访问者模式的优缺点,尤其是在操作多样化的数据结构时的优势。
- 提供在实际项目中的应用场景,如编译器、报表生成等。### 4.11 解释器模式解释器模式(Interpreter Pattern)为语言创建解释器,为某个语言定义它的文法表示,并建立一个解释器来解释这个语言中的句子。**代码示例**:```java
public interface Expression {int interpret();
}public class NumberExpression implements Expression {private int number;public NumberExpression(int number) {this.number = number;}public int interpret() {return number;}
}public class AddExpression implements Expression {private Expression leftExpression;private Expression rightExpression;public AddExpression(Expression leftExpression, Expression rightExpression) {this.leftExpression = leftExpression;this.rightExpression = rightExpression;}public int interpret() {return leftExpression.interpret() + rightExpression.interpret();}
}
扩展:
- 讨论解释器模式如何通过定义语言文法,简化语言解释的实现。
- 分析解释器模式的优缺点,尤其是在实现自定义语言和规则时的应用。
- 提供在实际项目中的应用场景,如SQL解析器、表达式计算器等。
5. 设计模式的应用与实践
5.1 如何选择合适的设计模式
在选择设计模式时,应根据具体的项目需求和场景,评估不同设计模式的适用性。开发者需要综合考虑代码的复杂性、可扩展性、维护成本等因素,选择最合适的设计模式。
5.2 设计模式在项目中的实际应用
在实际项目中,设计模式通常不是单独使用的,而是多种模式的组合。例如,工厂模式和单例模式可以结合使用,以创建和管理全局共享的资源。通过对实际项目的案例分析,可以更好地理解设计模式的实际应用。
5.3 设计模式的最佳实践
遵循设计模式的最佳实践有助于编写更高效、更健壮的代码。开发者应了解设计模式的适用场景和注意事项,避免模式滥用或误用。同时,及时更新和重构代码,以应对变化的需求和技术挑战。
5.4 设计模式的误用与反模式
虽然设计模式是开发的良好实践,但不当的使用可能导致复杂度增加、性能下降等问题。了解常见的反模式(如过度设计、滥用单例)有助于避免设计陷阱,提高代码质量。
6. 设计模式的扩展与创新
6.1 现代开发中的新模式与新方法
随着软件开发的不断发展,新的设计模式和方法也在不断涌现。例如,微服务架构、事件驱动设计等新模式正在逐步被广泛采用,开发者应当关注这些新趋势,并将其融入到实际开发中。
6.2 设计模式的组合与变种
设计模式在实践中往往需要组合使用,甚至需要根据具体需求进行变种。例如,组合使用策略模式和状态模式,可以实现更复杂的行为控制。通过灵活组合和变种设计模式,可以更好地满足复杂的业务需求。
6.3 设计模式与面向对象设计原则的结合
设计模式与面向对象设计原则(如SOLID原则)有着密切的关系。通过将设计模式与这些原则结合,可以创建更高质量的软件架构,提升代码的可维护性和可扩展性。
7. 总结
7.1 设计模式的学习与深入研究
设计模式是软件开发中的重要工具,通过系统学习和实践,可以提升设计能力。开发者应不断积累经验,深入研究设计模式的应用场景和扩展方法,以应对复杂的软件设计挑战。
7.2 设计模式在团队开发中的作用
在团队开发中,设计模式可以作为一种通用的设计语言,促进团队成员之间的沟通与协作。通过统一的设计模式,团队可以提高开发效率,减少沟通成本,并且确保代码的一致性和质量。
7.3 设计模式的未来发展趋势
随着技术的不断进步,设计模式也在不断演进。未来的设计模式将更加关注分布式系统、云计算、人工智能等新领域的应用。开发者应当保持对新技术的敏感性,不断学习和应用新模式,以应对未来的软件设计挑战。
相关文章:

Java设计模式详细讲解
目录 设计模式概述 1.1 什么是设计模式1.2 设计模式的类型1.3 设计模式的历史与发展1.4 设计模式在软件开发中的重要性 创建型模式 2.1 单例模式2.2 工厂方法模式2.3 抽象工厂模式2.4 建造者模式2.5 原型模式 结构型模式 3.1 适配器模式3.2 装饰器模式3.3 代理模式3.4 外观模…...

图论------弗洛伊德(Floyd-Warshall)算法
题目描述: 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的 T-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助…...

C#实现动画效果
在C#中,实现动画效果通常可以使用Windows Forms的Timer类或者使用System.Windows.Media.Animation命名空间下的类(如果是WPF应用)。以下是一个Windows Forms应用中使用Timer类来创建简单的动画效果的例子。 假设我们有一个窗体(F…...

Git 对比 SVN 的区别和优势
引言 版本控制系统(VCS)是软件开发过程中不可或缺的一部分,它们用于管理代码的变更、协调开发团队的工作。Git 和 SVN(Apache Subversion)是目前最流行的两个版本控制系统。本文将详细分析 Git 和 SVN 的区别及各自的…...

Qt实现无边框窗口的拖动和缩放
在使用QT创建窗体的时候,为了使窗口美化,通常不使用QT自带的边框。会调用下面函数去除窗体边框。 setWindowFlags(Qt::FramelessWindowHint) 但是有个问题,当去除了QT自带边框后,窗体就变得不能移动了,也不能改变窗口大…...

入门岛2-python实现wordcount并进行云端debug
书生大模型学习 任务: 1.实现一个wordcount函数,统计英文字符串中每个单词出现的次数。返回一个字典,key为单词,value为对应单词出现的次数。 2.Vscode连接InternStudio debug TIPS:记得先去掉标点符号,然后把每个单词…...

c语言-链表1
10 链表 一、链表是什么? -- 数据的一种存储方式 -- 链式存储 (1)线性存储 -- 地址连续 -- 自动开辟,自动释放 -- 默认是线性存储 (2)链式存储 -- 地址不连续…...

你好! Git——企业级开发模型
企业级开发模型(6) 一、删除远程分支,git branch -a (查看所有本地分支与远程分支)还能看到已经删除的分支,怎么解决?二、企业级开发流程2.1 企业级开发流程2.2 系统开发环境 三、Git分支设计模…...

力扣面试150 查找和最小的 K 对数字 最小堆 去重
Problem: 373. 查找和最小的 K 对数字 👨🏫 参考题解 class Solution {public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {// 创建一个大小为 k 的结果列表,用于存储和最小的 k 个数对List<Li…...

Oceanbase 执行计划
test100 CREATE TABLE `test100` ( `GRNT_CTR_NO` varchar(32) COLLATE utf8mb4_bin NOT NULL COMMENT 担保合同编号, `GRNT_CTR_TYP` varchar(3) COLLATE utf8mb4_bin NOT NULL COMMENT 担保合同类型, `COLC_GRNT_IND` varchar(1) COLLATE utf8mb4_bin DEFAULT NULL …...

精品丨模型关系介绍
PowerBI中的模型关系相信小伙伴们都不会感觉到陌生,因为一份优秀的报表无法离开数据模型的支撑。 对比其它BI类工具而言,白茶认为其建模功能才是最为突出的功能点。 模型关系类型 PowerBI中我们常用的模型关系一共包含5类: 一对一关系(1:1) …...

CentOS7 配置 nginx 和 php 方案
配置方案 一、安装软件二、编写配置文件,连接PHP三、引用文件四、测试 鉴于网上教程错综复杂,写下一这篇文章 本教程只需要三步即可 一、安装软件 yum install -y nginx php php-fpm二、编写配置文件,连接PHP 一般情况下在安装完 nginx 后…...

Promise.all全面解析:使用方法与实战技巧
Promise是JavaScript中处理异步操作的重要机制,它提供了一种优雅的方式来处理异步回调,避免了传统回调地狱的问题。而Promise.all作为Promise的一个静态方法,更是在处理多个异步操作时发挥着关键作用。本文将全面解析Promise.all的使用方法&a…...
NLP从零开始------9文本进阶处理之文本相似度计算
1.文本相似度计算简介 在自然语言处理中,经常会涉及度量两个文本相似度的问题。在诸如对话系统和信息减速等中,度量句子或短语之间的相似度尤为重要。在新闻学传媒中应用文本相似度可以帮助读者快速检索到想要了解的报道。 文本相似度的定义式如下所示&a…...

Electron 在 MAC 上的 build 签名应用配置
Electron 在 MAC 上的 build 签名应用配置涉及多个步骤,包括准备开发者账号、生成证书和配置文件、配置环境变量以及使用适当的工具进行签名和公证。以下是一个详细的配置流程: 一、准备开发者账号 首先,你需要在 Apple 开发者网站 注册并拥有一个开发者账号。这个账号将用…...

15 交换机命令行配置
交换机命令行配置 一、交换机命令行基本配置 (一)配置主机名 Switch>enable Switch#configure terminal Switch(config)#hostname S1(二)查看配置信息 Switch#show running-config Building configuration...Current confi…...

工作流之Flowable与SpringBoot结合
文章目录 1 Flowable1.1 flowable-ui部署运行1.2 绘制流程图1.2.1 绘制1.2.2 绘图细节1.2.3 bpmn文件导入 1.3 后台项目搭建1.3.1 pom.xml1.3.2 数据库表说明 1.4 流程引擎API与服务1.4.1 主要API1.4.2 示例 1 Flowable 1.1 flowable-ui部署运行 flowable-6.6.0 运行 官方dem…...

python实战:数据分析基础知识
当涉及到数据分析和统计建模时,Python 提供了强大的工具和库,如 pandas、numpy、statsmodels 和 matplotlib。本文将以一个实际的案例为例,介绍如何利用这些工具进行回归分析,并通过可视化工具进行结果展示和解释。 1. 背景介绍 …...

Grafana深入讲解
Grafana 深入讲解 目录 概述Grafana 基本概念 2.1 Grafana 简介2.2 Grafana 功能特性2.3 Grafana 架构 Grafana 安装与配置 3.1 安装 Grafana3.2 配置 Grafana3.3 验证 Grafana 安装 Grafana 数据源 4.1 支持的数据源类型4.2 添加数据源4.3 配置 Prometheus 数据源 Grafana 仪…...

002 git
下载 使用git clone命令下载特定分支 打开终端或命令行界面。 使用cd命令切换到你想存放仓库副本的本地目录。 使用以下命令克隆仓库的develop分支到本地(注意替换<仓库URL>为实际的仓库URL): git clone -b develop --single-branch…...

MySQL --- 用户管理
一、用户信息 MySQL中的用户信息,都存储在系统数据库mysql的表user中 user表的结构如下 这里主要介绍以下几个字段 host : 表示这个用户可以从哪个主机登陆,如果是 localhost ,表示只能从本机登陆 user: 用户名 a…...

Linux 错误码
目录 一、概述二、含义三、错误处理函数1、IS_ERR2、strerr、perror 一、概述 在 Linux 系统中,错误码是用来表示操作系统运行过程中发生的错误的数字代码。错误码通常由负数表示,0 表示成功,正数表示警告或其他非致命错误。 为了开发者更好…...

《向量数据库指南》——开源社区与商业化的平衡
开源社区与商业化的平衡 Lynn:我觉得这个说的特别好,因为开发者工具其实有很多,但是事实上真正去做开源的这种社区的,尤其是做的比较大的,其实这样的企业还是比较少的。那么当初在起步的时候就这么坚定的去选择开源,然后这么短的时间能获得这么多产品反馈。其实让我想到那…...

记录一次echarts图表大数据量轮询刷新页面卡死问题的优化
项目场景: 在我们的项目架构中,集成的Echarts图表组件采用了折线图,业务需求即每300毫秒自动更新图表上的数据,并且每一次的数据点数量达到了约700个,折线图刷新的很快,每300毫秒就要刷新数据 问题描述 开发过程中发现在这种数据量请求频率下,大概2个小时左右就会导致…...

补录:day023-回溯法
40.组合II 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 思路:组合题目二,这个题…...

【物联网】(防水篇)电子产品如何做到IPX7级别的防水?
电子产品如何做到IPX7级别的防水? 要使电子产品达到 IPX7 级别的防水,通常需要以下几个方面的措施: 1. 密封设计: 在产品的外壳连接处、接口、按键等部位,采用高质量的密封材料,如橡胶垫圈、硅胶密封圈等…...

JDK版本切换 - Windows
JDK 下载 点我跳转 - JDK下载官网 可以切换网址后面的JDK版本来跳转到不同的JDK版本下载页面 JDK 安装 双击exe文件即可安装最好是使用默认路径安装, 几个版本的JDK加起来也就1G如果双击exe文件没反应的话, 可以用**7-zip**解压出相应的文件 下载安装**7-zip**** - 默认路…...

STM32-IIC协议详解
一、IIC简介 IC(Inter-Integrated Circuit)协议由飞利浦公司于1980年代开发,是一种用于集成电路间短距离通信的串行协议。它设计用于连接低速外围设备,特别适合于需要简单数据交换的场景。IC协议使用两根信号线:SCL&am…...

Spring事件处理
Spring事件处理 1、核心概念2、线程模型3、监听上下文事件4、自定义事件 💖The Begin💖点点关注,收藏不迷路💖 1、核心概念 ApplicationContext:Spring的核心容器,负责管理Bean的生命周期,并支…...

软设之安全防范体系
安全防范体系的划分: 物理环境的安全性。包括通信线路,物理设备和机房的安全等。物理层的安全主要体现在通信线路的可靠性,软硬件设备的安全性,设备的备份,防灾害能力,防干扰能力,设备的运行环…...