Java八种常见的设计模式

一、单例模式

        单例模式是(Singleton Pattern)Java中最常用的设计模式之一,它保证一个类仅有一个实例,并提供一个全局访问点。

        实现单例模式的核心是将类的构造方法私有化,以防止外部直接通过构造函数创建实例。同时,类内部需要提供一个静态方法或变量来获取该类的唯一实例。单例模式分为饿汉式单例(立即加载)和懒汉式单例(延迟加载)。

饿汉式单例:线程安全

public class Singleton1 {/*** 在类的内部可以访问私有结构,所以可以在类的内部产生实例化对象*/private static Singleton1 instance = new Singleton1();/*** private 声明构造*/private Singleton1() {}/*** 返回对象实例*/public static Singleton1 getInstance() {return instance;}
}

懒汉式单例: 

        当多个线程并发执行 getInstance 方法时,懒汉式会存在线程安全问题,所以用到了 synchronized 来实现线程的同步,当一个线程获得锁的时候其他线程就只能在外等待其执行完毕。而饿汉式则不存在线程安全的问题。

public class Singleton2 {/*线程不安全*/
//    // 指向自己实例的私有静态引用
//    private static Singleton2 singleton2;
//
//    // 私有的构造方法
//    private Singleton2(){}
//
//    // 以自己实例为返回值的静态的公有方法,静态工厂方法
//    public static Singleton2 getSingleton2(){
//        // 被动创建,在真正需要使用时才去创建
//        if (singleton2 == null) {
//            singleton2 = new Singleton2();
//        }
//        return singleton2;
//    }/*** 声明变量*/private static volatile Singleton2 singleton = null;/*** 私有构造方法*/private Singleton2() {}/*** 提供对外方法* @return*/public static Singleton2 getInstance() {// 还未实例化if (singleton == null) {synchronized (Singleton2.class) {if (singleton == null) {singleton = new Singleton2();}}}return singleton;}
}

JDK 中的应用:

  • java.lang.Runtime.getRuntime()
  • java.util.logging.Logger

Spring 中的应用:Spring 的 Bean 默认是单例模式。可以通过 @Scope("prototype") 将其改为多例。

二、工厂模式

根据需求,在用于不同的场景下,创建不同的对象。

public interface Sender {void Send();
}public class MailSender implements Sender{@Overridepublic void Send() {System.out.println("This is mail sender...");}
}public class SmsSender implements Sender{@Overridepublic void Send() {System.out.println("This is sms sender...");}
}public class FactoryPattern {public static void main(String[] args) {Sender sender = produce("mail");sender.Send();}public static Sender produce(String str) {if ("mail".equals(str)) {return new MailSender();} else if ("sms".equals(str)) {return new SmsSender();} else {System.out.println("输入错误...");return null;}}
}

        在此基础上,若存在多个分支判断条件,很容易出现传递的字符串出错,则不能正确创建对象,因此可以多封装一个类,用来将分支判断替换为每个方法,降低耦合,这种模式是多个工厂方法模式,是提供多个工厂方法,分别创建对象。 

public interface Sender {void Send();
}public class MailSender implements Sender{@Overridepublic void Send() {System.out.println("This is mail sender...");}
}public class SmsSender implements Sender{@Overridepublic void Send() {System.out.println("This is sms sender...");}
}public class SendFactory {public Sender produceMail() {return new MailSender();}public Sender produceSms() {return new SmsSender();}
}public class FactoryPattern {public static void main(String[] args) {SendFactory factory = new SendFactory();Sender sender = factory.produceMail();sender.Send();}
}

JDK 中的应用:

  • java.util.Calendar.getInstance()
  • javax.xml.parsers.DocumentBuilderFactory.newInstance()

Spring 中的应用:

  • BeanFactory 和 ApplicationContext 都是工厂模式的体现。

 三、建造者模式

        建造者模式用于创建复杂对象,就是将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合起来构建出复杂对象。

角色组成:

  1. 产品类(Product):表示被创建的复杂对象。它通常包含多个部分或者组成,并由具体的建造者逐步构建而成。 Meal
  2. 抽象建造者类(Builder):定义了建造复杂对象所需要的各个部分的创建方法。它通常包括多个构建方法和一个返回产品的方法。 MealBuilder
  3. 具体建造者类(ConcreteBuilder):实现Builder接口,并提供各个部分或者组成的构建方法。 BeefBurgerMealBuilder、ChickenMealBuilder、ShrimpMealBuilder
  4. 指挥者类(Director):负责控制建造者的构建顺序,指挥建造者如何构建复杂对象。MealDirector
/*** @Author: EstellaQ* @Date: 2025/4/17 15:43* @Description: 产品类**/
@Data
public class Meal {//汉堡包private String burger;//薯条private String fries;//饮料private String drink;}/*** @Author: EstellaQ* @Date: 2025/4/17 15:44* @Description: 建造者接口**/
public interface MealBuilder {Meal meal=new Meal();//构建汉堡public void buildBurger();//构建薯条public void buildFries();//构建饮料public void buildDrink();public default Meal getMeal(){return meal;}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:46* @Description:  牛肉套餐建造者**/
public class BeefBurgerMealBuilder implements MealBuilder{@Overridepublic void buildBurger() {meal.setBurger("牛肉汉堡");}@Overridepublic void buildFries() {meal.setFries("大份薯条");}@Overridepublic void buildDrink() {meal.setDrink("中杯可乐");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:46* @Description: 鸡肉套餐建造者**/
public class ChickenMealBuilder implements MealBuilder{@Overridepublic void buildBurger() {meal.setBurger("鸡肉汉堡");}@Overridepublic void buildFries() {meal.setFries("中份薯条");}@Overridepublic void buildDrink() {meal.setDrink("大杯果汁");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:46* @Description: 虾肉套餐建造者**/
public class ShrimpMealBuilder implements MealBuilder{@Overridepublic void buildBurger() {meal.setBurger("虾肉汉堡");}@Overridepublic void buildFries() {meal.setFries("小份薯条");}@Overridepublic void buildDrink() {meal.setDrink("大杯芬达");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:50* @Description: 指挥者**/
public class MealDirector {private MealBuilder mealBuilder;public void setMealBuilder(MealBuilder mealBuilder){this.mealBuilder=mealBuilder;}public Meal getMeal(){return mealBuilder.getMeal();}//制作套餐public void constructMeal(){mealBuilder.buildBurger();mealBuilder.buildFries();mealBuilder.buildDrink();}
}public class BuilderPattern {public static void main(String[] args) {//创建指导者MealDirector director=new MealDirector();//执导建造牛肉套餐director.setMealBuilder(new BeefBurgerMealBuilder());director.constructMeal();Meal meal = director.getMeal();System.out.println("牛肉套餐:"+meal.toString());//鸡肉套餐director.setMealBuilder(new ChickenMealBuilder());director.constructMeal();Meal meal2 = director.getMeal();System.out.println("鸡肉套餐:"+meal2.toString());//虾肉套餐director.setMealBuilder(new ShrimpMealBuilder());director.constructMeal();Meal meal3 = director.getMeal();System.out.println("虾肉套餐:"+meal3.toString());}
}

JDK 中的应用:

  • StringBuilder
  • Stream.Builder

Spring 中的应用:

  • UriComponentsBuilder 用于构建 URI。

 四、 适配器模式

        它允许将不兼容的对象转换成可兼容的接口。主要目的是解决在不改变现有代码的情况下,使不兼容的接口之间能够正常工作,通过创建一个中间转换的适配器来将一个对象转换成我们所需要的接口。

角色组成

  • 目标接口(target):需要适配的标准接口。
  • 源对象(source):需要被适配的不兼容对象。
  • 适配器对象(adapter):充当中间转换角色,该对象将源对象转换成目标接口。
/*** @Author: EstellaQ* @Date: 2025/4/17 16:20* @Description: 目标接口**/
public interface Target {/*** 翻译* @param source 母语* @param target 要翻译成的语种* @param words 内容*/void translate(String source,String target,String words);
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:20* @Description: 源对象**/
public class Translator {//英——》汉public void translateInZh(String words){if("hello world!".equals(words)){System.out.println("翻译成中文:”你好世界!“");}}//汉——》英public void translateInEn(String words){if("你好世界!".equals(words)){System.out.println("Translate in English:”hello world!“");}}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:21* @Description: 类适配器:通过多重继承目标接口和被适配者类方式来实现适配**/
public class ClassAdapter extends Translator implements Target{@Overridepublic void translate(String source, String target, String words) {if("中文".equals(source) && "英文".equals(target)) {//汉--》英this.translateInEn(words);} else {//英--》汉this.translateInZh(words);}}
}public class AdapterPattern {public static void main(String[] args) {//创建一个类适配器对象ClassAdapter adapter=new ClassAdapter();adapter.translate("中文", "英文", "你好世界!");adapter.translate("英语","中文","hello world!");}
}

 五、 装饰器模式

装饰器模式在不改变原始类的基础上,动态累积扩展其功能。原始对象和装饰类对象都要实现原始对象的接口。

/*** @Author: EstellaQ* @Date: 2025/4/17 16:55* @Description: 原始对象的接口**/
public interface ICoffee {void makeCoffee();
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:56* @Description: 原始对象**/
public class OriginalCoffee implements ICoffee{@Overridepublic void makeCoffee() {System.out.print("原味咖啡 ");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:56* @Description: 装饰器基类**/
public abstract class CoffeeDecorator implements  ICoffee{private  ICoffee coffee;public CoffeeDecorator(ICoffee coffee){this.coffee=coffee;}@Overridepublic void makeCoffee() {coffee.makeCoffee();}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:58* @Description: 加奶的装饰**/
public class MilkDecorator extends CoffeeDecorator{public MilkDecorator(ICoffee coffee) {super(coffee);}@Overridepublic void makeCoffee() {super.makeCoffee();addMilk();}private void addMilk(){System.out.print("加奶 ");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:58* @Description: 加糖的装饰**/
public class SugarDecorator extends CoffeeDecorator{public SugarDecorator(ICoffee coffee) {super(coffee);}@Overridepublic void makeCoffee() {super.makeCoffee();addSugar();}private void addSugar(){System.out.print("加糖 ");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:00* @Description: 装饰器模式测试**/
public class DecoratorPattern {public static void main(String[] args) {//原味咖啡ICoffee coffee=new OriginalCoffee();coffee.makeCoffee();System.out.println("");//加奶的咖啡coffee=new MilkDecorator(coffee);coffee.makeCoffee();System.out.println("");//先加奶后加糖的咖啡coffee=new SugarDecorator(coffee);coffee.makeCoffee();}
}

JDK 中的应用:

  • java.io.BufferedInputStream 和 java.io.BufferedOutputStream

Spring 中的应用:

  • BeanPostProcessor 用于动态修改 Bean 的行为。

六、 代理模式

        代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问,下面来分析其基本结构。

角色组成:

  • 抽象主题(Subject)类(业务接口类):通过接口或抽象类声明真实主题和代理对象实现的业务方法,服务端需要实现该方法。
  • 真实主题(Real Subject)类(业务实现类):实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

静态代理 

        静态代理服务于单个接口,我们来考虑实际工程中的一个例子,现在已经有业务代码实现一个增删功能,原有的业务代码由于仍有大量程序无法改变,现在新增需求,即以后每执行一个方法输出一个日志。

/*** @Author: EstellaQ* @Date: 2025/4/17 17:38* @Description: 业务接口**/
public interface DateService {void add();void del();
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:39* @Description: 委托类**/
public class DateServiceImplA implements DateService{@Overridepublic void add() {System.out.println("成功添加!");}@Overridepublic void del() {System.out.println("成功删除!");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:40* @Description: 代理类**/
public class DateServiceProxy implements DateService{DateServiceImplA server = new DateServiceImplA();@Overridepublic void add() {server.add();System.out.println("程序执行add方法,记录日志.");}@Overridepublic void del() {server.del();System.out.println("程序执行del方法,记录日志.");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:39* @Description: 代理模式测试**/
public class ProxyPattern {public static void main(String[] args) {DateService service = new DateServiceProxy();service.add();service.del();}
}

动态代理 

        动态代理可以帮助我们仅仅在需要的时候再创建代理类,减少资源浪费,此外由于动态代理是一个模板的形式,也可以减少程序的代码量,例如在静态代码示例中,我们在每个方法中加入System.out.println("程序执行***方法,记录日志.");,当业务方法非常多时,我们也得为每个业务方法加上记录日志的语句,而动态代理中将方法统一管理,无论几个业务方法都只需要一条记录语句即可实现,具体请看代码。

/*** @Author: EstellaQ* @Date: 2025/4/17 17:48* @Description: 动态代理的代理类**/
public class ProxyInvocationHandler implements InvocationHandler {private DateService service;public ProxyInvocationHandler(DateService service) {this.service = service;}public Object getDateServiceProxy() {return Proxy.newProxyInstance(this.getClass().getClassLoader(), service.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {var result = method.invoke(service, args); // 让service调用方法,方法返回值System.out.println(proxy.getClass().getName() + "代理类执行" + method.getName() + "方法,返回" + result +  ",记录日志!");return result;}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:39* @Description: 代理模式测试**/
public class ProxyPattern {public static void main(String[] args) {
//静态代理
//        DateService service = new DateServiceProxy();
//        service.add();
//        service.del();
//动态代理DateService serviceA = new DateServiceImplA();DateService serviceProxy = (DateService) new ProxyInvocationHandler(serviceA).getDateServiceProxy();serviceProxy.add();serviceProxy.del();}
}

七、 策略模式

        该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。  我认为跟工厂模式的思想很相似    

角色组成:  

抽象策略(Strategy)类
具体策略(Concrete Strategy)类
环境(Context)类

/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 抽象算法的策略类,定义所有支持的算法的公共接口**/
public interface Strategy {/*** 算法方法*/public void AlgorithmInterface();
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 策略实现类A**/
public class ConcreteStrategyA implements Strategy{@Overridepublic void AlgorithmInterface() {System.out.println("算法A的实现");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 策略实现类B**/
public class ConcreteStrategyB implements Strategy{@Overridepublic void AlgorithmInterface() {System.out.println("算法B的实现");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 策略实现类C**/
public class ConcreteStrategyC implements Strategy{@Overridepublic void AlgorithmInterface() {System.out.println("算法C的实现");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:06* @Description: 上下文,维护一个对策略类对象的引用**/
public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void contextInterface(){strategy.AlgorithmInterface();}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:03* @Description: 策略模式的测试类**/
public class StrategyPattern {public static void main(String[] args) {Context context;context = new Context(new ConcreteStrategyA());context.contextInterface();context = new Context(new ConcreteStrategyB());context.contextInterface();context = new Context(new ConcreteStrategyC());context.contextInterface();}
}

JDK 中的应用:

  • java.util.Comparator 是典型的策略模式。

Spring 中的应用:

  • 事务管理(TransactionManager),支持编程式和声明式事务。

八、 观察者模式

        观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

角色组成:

  • 主题(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。
  • 观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
  • 具体主题(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。
  • 具体观察者(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。
/*** @Author: EstellaQ* @Date: 2025/4/17 18:42* @Description: 主题类,被观察者**/
public class Subject {private List<Observer> observers = new ArrayList<Observer>();private int state;public int getState() {return state;}public void setState(int state) {this.state = state;notifyAllObservers();}public void attach(Observer observer){observers.add(observer);}public void notifyAllObservers(){for (Observer observer : observers) {observer.update();}}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:43* @Description: 被通知者的抽象类**/
public abstract class Observer {protected Subject subject;public abstract void update();}/*** @Author: EstellaQ* @Date: 2025/4/17 18:46* @Description: 被通知者的实现类**/
public class BinaryObserver extends Observer{public BinaryObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Binary String: "+ Integer.toBinaryString( subject.getState() ) );}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:46* @Description: 被通知者的实现类**/
public class OctalObserver extends Observer{public OctalObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Octal String: "+ Integer.toOctalString( subject.getState() ) );}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:46* @Description: 被通知者的实现类**/
public class HexaObserver extends Observer{public HexaObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Hex String: "+ Integer.toHexString( subject.getState() ) );}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:48* @Description: 观察者模式测试**/
public class ObserverPattern {public static void main(String[] args) {Subject subject = new Subject();new HexaObserver(subject);new OctalObserver(subject);new BinaryObserver(subject);System.out.println("First state change: 15");subject.setState(15);System.out.println("Second state change: 10");subject.setState(10);}
}

JDK 中的应用:

  • java.util.Observer 和 java.util.Observable
  • javax.swing.event.ChangeListener

Spring 中的应用:

  • ApplicationEvent 和 ApplicationListener 是典型实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/77284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4.17---实现商铺和缓存与数据库双写一致以及宕机处理

实现商铺和缓存与数据库双写一致&#xff08;以及强双写一致策略&#xff09; redis点评项目采用的是延时双删策略 双删&#xff1a; 我们更新完数据库之后删除缓存&#xff0c;这样即使有线程并发进来查询&#xff0c;会发现缓存中没有数据&#xff0c;从而会去mysql中查找…

滑动窗口209. 长度最小的子数组

1.题目 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 1&#xff1a; 输入&…

osu ai 论文笔记 DQN

e https://theses.liacs.nl/pdf/2019-2020-SteeJvander.pdf Creating an AI for the Rhytm Game osu! 20年的论文 用监督学习训练移动模型100首歌能达到95准确率 点击模型用DQN两千首歌65准确率 V抖用的居然不是强化学习&#xff1f; 5,6星打96准确度还是有的东西的 这是5.…

如何通过工具实现流程自动化

通过自动化工具&#xff0c;企业可以显著提高工作效率、降低人为错误、节省时间和成本。现代企业的运营中&#xff0c;流程管理是确保工作顺畅的关键&#xff0c;而人工处理繁琐的流程不仅容易出错&#xff0c;还会消耗大量的时间和人力资源。通过使用适合的自动化工具&#xf…

mongodb 4.0+多文档事务的实现原理

1. 副本集事务实现&#xff08;4.0&#xff09;‌ ‌非严格依赖二阶段提交‌ MongoDB 4.0 在副本集环境中通过 ‌全局逻辑时钟&#xff08;Logical Clock&#xff09;‌ 和 ‌快照隔离&#xff08;Snapshot Isolation&#xff09;‌ 实现多文档事务&#xff0c;事务提交时通过…

《理解 Java 泛型中的通配符:extends 与 super 的使用场景》

大家好呀&#xff01;&#x1f44b; 今天我们要聊一个让很多Java初学者头疼的话题——泛型通配符。别担心&#xff0c;我会用最通俗易懂的方式&#xff0c;带你彻底搞懂这个看似复杂的概念。准备好了吗&#xff1f;Let’s go! &#x1f680; 一、为什么我们需要泛型通配符&…

速盾:高防CDN访问多了会影响源站吗?

在当今数字化时代&#xff0c;内容分发网络&#xff08;CDN&#xff09;已经成为保障网站性能和用户体验的重要工具。特别是高防CDN&#xff0c;它不仅能够加速内容传输&#xff0c;还能有效抵御各种类型的网络攻击&#xff0c;确保业务的连续性和稳定性。然而&#xff0c;一些…

Unity URP Moblie AR示例工程,真机打包出来,没阴影

效果&#xff1a; unity ar示例演示 现象&#xff1a; 真机打包测试私活没有阴影 Unity版本&#xff1a;2022.3.4f1c1 分析原因&#xff1a; Prefab &#xff1a;ARFeatheredPlane中也有材质&#xff0c;一个用于环境遮挡&#xff0c;一个用于阴影接受。 按理说有啊。 urp …

win10下github libiec61850库编译调试sntp_example

libiec61850 https://github.com/mz-automation/libiec61850 v1.6 简介 libiec61850 是一个开源&#xff08;GPLv3&#xff09;的 IEC 61850 客户端和服务器库实现&#xff0c;支持 MMS、GOOSE 和 SV 协议。它使用 C 语言&#xff08;根据 C99 标准&#xff09;实现&#xf…

Microsoft SQL Server Management 一键删除数据库所有外键

DECLARE ESQL VARCHAR(1000); DECLARE FCursor CURSOR --定义游标 FOR (SELECT ALTER TABLE O.name DROP CONSTRAINT F.name; AS CommandSQL from SYS.FOREIGN_KEYS F JOIN SYS.ALL_OBJECTS O ON F.PARENT_OBJECT_ID O.OBJECT_ID WHERE O.TYPE U AND F.TYPE …

新型多机器人协作运输系统,轻松应对复杂路面

受到鱼类、鸟类和蚂蚁等微小生物体协作操纵的启发&#xff0c;研究人员开发了多机器人协作运输系统&#xff08;Multirobot Cooperative Transportation Systems&#xff0c;MRCTS&#xff09;运输单个机器人无法处理的重型超大物体&#xff0c;可用于搜救行动、灾难响应、军事…

Framework Binder架构分解

整个 Binder 架构所涉及的总共有以下 5 个目录&#xff1a; 1. /framework/base/core/java/(Java) 2. /framework/base/core/jni/ (JNI) 3&#xff0c;/framework/native/libs/binder (Native) 4&#xff0c;/framework/native/cmds/servicemanager/ (Native) 5&#xff0c…

腾讯云对象存储以及项目业务头像上传

腾讯云上传步骤&#xff1a; service-vod模块化中 ①、参考文档&#xff0c;引入依赖 ②、配置文件application.properties ③、创建工具类 初始化bean的时候读取配置文件 Component public class ConstantPropertiesUtil implements InitializingBean{Value("${t…

LeetCode hot 100—括号生成

题目 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()","()(())",&…

SpringBoot企业级开发之【文章分类-新增文章分类】

看一下新增文章的需求&#xff1a; 接口文档&#xff1a; 开发思路&#xff1a; 先在controller下去创建add方法&#xff0c;方法内导入Service类获取add的结果&#xff1b;再在Service接口下去创建add的方法&#xff1b;然后在Service实现类下去实现方法的作用&#xff0c;且导…

Minecraft盔甲机制详解(1.9之后)

Minecraft的盔甲有很多种&#xff0c;但是评判盔甲的好坏&#xff0c;通常玩家会使用一个变量来评判——护甲值 护甲值的机制很简单&#xff0c;一格护甲值 &#xff08;半个灰色的衣服图标&#xff09;最多能提供4%的防御 护甲值在不开作弊的生存模式理论上限是20点&#xf…

为什么要给单片机植入操作系统

给单片机植入操作系统&#xff08;通常是实时操作系统&#xff0c;RTOS&#xff09;主要是为了在资源有限的环境中实现更高效、更可靠的多任务管理和系统调度。以下是主要原因和优势&#xff1a; 1. 多任务并行处理 背景&#xff1a;单片机通常需要同时处理多个任务&#xff0…

Arduino+ESP826601s模块连接阿里云并实现温湿度数据上报

ArduinoESP826601s模块连接阿里云并实现温湿度数据上报 一、前言二、准备工作三、程序代码1. Arduino的程序2. ESP826601的程序3. 上面程序需要注意的地方 四、运行结果五、结束语 一、前言 看完我这三篇文章&#xff0c;相信各位朋友对于阿里云物联网平台的使用都有了一定的认…

Java 工厂设计模式详解:用统一入口打造灵活可扩展的登录系统----掌握 Spring 源码的基础第一步

一、前言 在实际开发中&#xff0c;我们经常面临以下场景&#xff1a; 系统支持多种登录方式&#xff08;用户名密码、管理员登录、OAuth 登录、短信登录等&#xff09; 每种登录方式的认证逻辑不同 我们希望对外提供一个统一的接口调用&#xff0c;而不暴露具体实现 这个…

Windows Acrobat Pro DC-v2025.001.20435-x64-CN-Portable便携版

Windows Acrobat Pro 链接&#xff1a;https://pan.xunlei.com/s/VOO1nMjQ1Qf53dyISGne0c_9A1?pwdsfgn# Acrobat Pro 2024 专业增强版特色 ● 创建和编辑 PDF 文件&#xff1a;可以将各种类型的文档转换为 PDF 格式&#xff0c;并进行编辑和修改。 ● 合并和拆分 PDF&#…