设计模式学习笔记--单例、建造者、适配器、装饰、外观、组合
以下内容根据以下网址及相关视频整理:Android设计模式之单例模式_谬谬清不给我取名字的博客-CSDN博客_android 单例模式
Android设计模式--单例模式的六种实现和单例模式讲解Volatile与Synchronized相关的并发_龙腾腾的博客-CSDN博客_android 单例 volatile
java 设计模式实战,装饰者模式之不用改变也能变强 - 掘金
目录
一、单例模式:
1、饿汉式单例模式:
2、懒汉式单例模式:
3、双重检索(Double Check Lock,DCL)
4、静态内部类实现单例
5、使用 枚举实现单例
二、builder模式---将复杂的对象构建分离
三、adapter设计模式
1.类适配器:把适配的类的API转换成目标类的API。
2.对象适配器模式:
四、装饰模式
五、外观模式
六、组合模式
一、单例模式:
(1)构造方法使用private修饰,避免外部通过new创建对象;
(2)通过一个静态方法或者枚举返回单例类对象;
(3)考虑对象创建时的线程安全问题,确保单例类的对象有且仅有一个,尤其是在多线程环境下;
(4)确保单例类对象在反序列化时不会重新构建对象;
1、饿汉式单例模式:
(1)类加载时就初始化,浪费内存,不能延迟加载;
(2)基于 classloader 机制避免了多线程的同步问题,线程安全;
(3)没有加锁,调用效率高;
public class Singleton {private static Singleton sInstance = new Singleton();private Singleton() {}public static Singleton getInstance() {return sInstance;}
}
2、懒汉式单例模式:
(1)可以延迟加载;
(2)加synchronized是线程安全的,不加就是线程不安全的;
(3)加synchronized会导致调用效率很低;
不足之处:在多线程并发下这样的实现是无法保证实例是唯一的。
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}
优化:懒汉线程安全模式
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}//方法一:添加 synchronized 关键字public static synchronized LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}//方法二:同步代码块实现public static LazySingleton getInstance2() {synchronized (LazySingleton.class) {if (instance == null) {instance = new LazySingleton();}}return instance;}
}
缺点:性能方面不足
3、双重检索(Double Check Lock,DCL)
(1)可以延迟加载;
(2)线程安全的;
(3)对JDK的版本有要求(1.5及以上)(需要使用volatile关键字来禁止指令重排的操作,这个在JDK1.5之后才出现)
public class Singleton {private volatile static Singleton instance; //volatile具备 “有序性” 和 “可见性” 的特性。 第一层锁:保证变量可见性private Singleton() {}public static Singleton getInstance() {if (instance == null) {//第一次判空:无需每次都加锁,提高性能synchronized (Singleton.class) {//第二层锁:保证线程同步if (instance == null) {//第二次判空:避免多线程同时执行getInstance()产生多个single对象instance = new Singleton();}}}return instance;}
}
1)、构造函数得私有,禁止其他对象直接创建实例;
2)、对外提供一个静态方法,可以获取唯一的实例;
3)、即然是双重检查模式,就意味着创建实例过程会有两层检查。第一层就是最外层的判空语句:第一处if (singleton == null),该判断没有加锁处理,避免第一次检查singleton对象非null时,多线程加锁和初始化操作;当前对象未创建时,通过synchronized关键字同步代码块,持有当前Singleton.class的锁,保证线程安全,然后进行第二次检查。
4)、Singleton类持有的singleton实例引用需要volatile关键字修饰,因为在最后一步singleton = new Singleton(); 创建实例的时候可能会重排序,导致singleton对象逸出,导致其他线程获取到一个未初始化完毕的对象。
4、静态内部类实现单例
(1)可以延迟加载;
(2)基于 classloader 机制避免了多线程的同步问题,线程安全;没有性能缺陷;
public class Singleton{private Singleton(){}public static Singleton newInstance(){return SingletonHelper.instance;}//静态内部类 唯一性 私有的private static class SingletonHelper{private final static Singleton instance = new Singleton();}
}
5、使用 枚举实现单例
优点:
(1)不是延迟加载的;
(2)枚举实例的创建是线程安全的,并且在任何情况下都是一个单例;
public enum Singleton {INSTANCE;
}
总结:
饿汉:无法对instance实例进行延迟加载。
懒汉:多线程并发条件下无法保证实例的唯一性。
懒汉线程安全:使用synchronized 关键字导致性能缺陷。
DCL:JVM即编译器指令导致重排序,导致实例可能不唯一。
静态内部类、枚举:延迟加载、线程安全、性能优势。
android中用到的单例模式举例:application、eventBus
public class MyApplication extends Application {private static MyApplication instance;public static MyApplication getInstance() {return instance;}@Overridepublic void onCreate() {super.onCreate();instance = this;} }
通过MyApplication.getInstance()获取MyApplication类;
二、builder模式---将复杂的对象构建分离
builder模式也叫建造者模式,是较为复杂的 创建型模式,它将客户端与包含多个组成部分(或部件)的复杂对象的创建过程分离。 builder模式的作用将一个复杂对象的构建与他的表示分离,使用者可以一步一步的构建一个比较复杂的对象。
使用场景:当构建一个对象需要很多参数的时候,并且参数的对象和类型不固定的时候。
//Product:被构建的复杂对象,包含多个组成部件
public class Product {private String partA;private String partB;private String partC;public String getPartA() {return partA;}public void setPartA(String partA) {this.partA = partA;}public String getPartB() {return partB;}public void setPartB(String partB) {this.partB = partB;}public String getPartC() {return partC;}public void setPartC(String partC) {this.partC = partC;}
}//Builder:它为创建一个产品Product对象的各个部件指定抽象接口
abstract class Builder {protected Product product = new Product();//创建产品对象public abstract void buildPartA();public abstract void buildPartB();public abstract void buildPartC();//用于返回复杂的产品对象public Product getResult() {return product;}
}//ConcreateBulder:实现了Builder接口,实现各个部件的具体构造和装配方法
public class ConcreateBulder extends Builder {@Overridepublic void buildPartA() {}@Overridepublic void buildPartB() {}@Overridepublic void buildPartC() {}
}//指挥类:作用:隔离程序员创建复杂对象的过程;控制产品创建复杂对象的过程
//Director:指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系。
public class Director {public Builder builder;public Director(Builder builder) {this.builder = builder;}public void setBuilder(Builder builder) {this.builder = builder;}//产品构建和组装的方法public Product construct() {builder.buildPartA();builder.buildPartB();//每一个部分可以灵活选择是否实现builder.buildPartC();return builder.product;}
}//调用类:class BuildClient{public static void main(String[] args){Builder builder = new ConcreateBulder();Director director = new Director(builder);director.construct();}
}
总结:
(1)Product:被构建的复杂对象,包含多个组成部件
(2)Builder:它为创建一个产品Product对象的各个部件指定抽象接口
(3)ConcreateBulder:实现了Builder接口,实现各个部件的具体构造和装配方法
(4)Director:指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系。
优点:
松散耦合:生成器模式可以用同一个构造算法构建出表现上完全不同的产品,实现产品构建和产品表现上的分离。
可以很容易的改变产品的内部展示。
更好的复用性:生成器模式很好的实现构建算法和具体产品实现的分离。
缺点:
会产生多余的builder对象以及director对象,消耗内存。
对象的构建过程会暴露。
builder模式在android中的应用:AlertDialog、
三、adapter设计模式
定义:将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器。
1.类适配器:把适配的类的API转换成目标类的API。
让 Adapter
实现 Target
接口,并且 继承 Adaptee
,这样 Adapter
就具备 Target
和 Adaptee
可以将两者进行转化。
//目标角色:所期待得到的接口,类适配器目标不能为类
public interface Target {void sampleOperation2();
}//源角色:现在需要适配的接口,
public class Adaptee {public void sampleOperation1(){System.out.println("打印1212");}
}
//适配器角色:适配器类是本模式的核心,适配器把源接口转换成目标接口,这一角色必须是类
public class Adapter extends Adaptee implements Target {@Overridepublic void sampleOperation2() {super.sampleOperation1();}
}public class Client {public static void main(String[] args) {Target target = new Adapter();target.sampleOperation2();}
}
总结:
1、类适配器使用对象继承的方式,是静态的定义方式。
2、对于类适配器,适配器可以重定义adapteree的部分行为。
3、对于类适配器,仅仅引用了一个对象,并不需要额外的引用来间接获得adapteree.
4、由于适配器直接继承了adapteree,使得适配器不能和adapteree的子类一起工作。
2.对象适配器模式:
对象适配器的原理就是通过组合来实现适配器功能,是动态组合的方式。具体做法:让Adapter 实现 Target 接口,然后内部持有 Adaptee 实例,然后再 Target 接口规定的方法内转换 Adaptee。 具体代码实现很简单就是将Adapter代码修改一下,原来是继承 Adaptee,现在是持有 Adaptee。
public interface Target {void sampleOperation2();
}public class Adaptee {public void sampleOperation1(){System.out.println("打印1212");}
}public class Adapter implements Target {public Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void sampleOperation2() {adaptee.sampleOperation1();}
}public class Client {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Adapter adapter = new Adapter(adaptee);adapter.sampleOperation2();}
}
四、装饰模式
定义:动态地给对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类实现更加灵活,装饰模式是一种对象结构型模式。
使用场景:
1)在不影响其它对象的情况下,以动态、透明的方式给单个对象添加新的行为或特征
2)当不能采用继承的方式对系统进行扩展或采用继承不利于系统的扩展和维护时,采用装饰模式。
代码:
//抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。 人:吃、跑
public interface People {void run();void eat();
}//具体构件(Concrete Component)角色:定义一个将要接收附加责任的类
public class Xiaoming implements People{@Overridepublic void run() {System.out.println("小明正在跑步。。。");}@Overridepublic void eat() {System.out.println("小明正在吃饭。。。");}
}//装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
public abstract class PeopleDetail implements People {private People people;public PeopleDetail(People people) {this.people = people;}@Overridepublic void run() {beforeRun();people.run();afterRun();}@Overridepublic void eat() {beforeEat();people.eat();afterEat();}public abstract void beforeEat();public abstract void afterEat();public abstract void beforeRun();public abstract void afterRun();
}//具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。
public class XiaomingRun extends PeopleDetail{public XiaomingRun(People people) {super(people);}@Overridepublic void beforeEat() {}@Overridepublic void afterEat() {}@Overridepublic void beforeRun() {System.out.println("小明先做拉伸训练");}@Overridepublic void afterRun() {System.out.println("小明进入慢走路状态");}
}//具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。
public class XiaomingEat extends PeopleDetail{public XiaomingEat(People people) {super(people);}@Overridepublic void beforeEat() {System.out.println("小明喝了一杯水");}@Overridepublic void afterEat() {System.out.println("小明出去走了100步");}@Overridepublic void beforeRun() {}@Overridepublic void afterRun() {}
}//接下来进行测试:public static void main(String[] args){Xiaoming xiaoming = new Xiaoming();System.out.println("小明开始吃饭--");XiaomingEat xiaomingEat = new XiaomingEat(xiaoming);xiaomingEat.eat();System.out.println("小明开始跑步--");XiaomingRun xiaomingRun =new XiaomingRun(xiaoming);xiaomingRun.run();}
优点:对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加。降低了系统的耦合度;可以动态扩展一个实现类的功能。
五、外观模式
定义:主要目的在于让外部减少与子系统内部多个模块的交互,从而让外部能够更简单的使用子系统,它负责把客户端的请求转发给子系统内部的各个模块进行处理。
使用场景:
1)当你要为一个复杂子系统提供一个简单接口时。
2)客户程序与抽象类的实现部分之间存在着很大的依赖性。
3)当你需要构建一个有层次结构的子系统时。
//抽象的组件
public interface Module {void work();
}//实例
public class Module1 implements Module{@Overridepublic void work() {System.out.println("Module1");}
}public class Module2 implements Module{@Overridepublic void work() {System.out.println("Module2");}
}public class Module3 implements Module{@Overridepublic void work() {System.out.println("Module3"+"改变了");}
}public class ModuleImpl {private Module1 module1 = null;private Module3 module3= null;private Module2 module2= null;private static ModuleImpl moduleImpl = null;private ModuleImpl(){this.module1 = new Module1();this.module2 = new Module2();this.module3 = new Module3();}public static ModuleImpl getInstance(){if (moduleImpl==null){moduleImpl = new ModuleImpl();}return moduleImpl;}public void testModule(){module1.work();module2.work();module3.work();}
}//测试:ModuleImpl.getInstance().testModule();
优点:
1)由于ModuleImpl 封装了各个模块交互的过程,如果今后内部模块调用发生了变化,只需要修改ModuleImpl 类就可以。
2)ModuleImpl 是单例的,是可以被多个客户端调用的。
六、组合模式
定义:将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端和单个对象和组合对象的使用具有一致性。
树的结构——>组合设计模式
使用场景:
1)需要表示一个对象整体或者部分层次。
2)让客户能够忽略不同对象层次的变化。
public abstract class File {private String name;public File(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public abstract void Watch();//以下三个方法是组合方法public void add(File file) {throw new UnsupportedOperationException();}public void remove(File file) {throw new UnsupportedOperationException();}public File getChild(int positon) {throw new UnsupportedOperationException();}
}public class Folder extends File {public List<File> mFileList;public Folder(String name) {super(name);mFileList = new ArrayList<>();}@Overridepublic void Watch() {StringBuffer fileName = new StringBuffer();for (File file : mFileList) {fileName.append(file.getName() + ":");}System.out.println("组合模式:"+"这是一个叫"+getName()+"文件夹,包含:"+mFileList.size()+"个文件,分别是:"+fileName);}@Overridepublic void add(File file) {mFileList.add(file);}@Overridepublic void remove(File file) {mFileList.remove(file);}@Overridepublic File getChild(int positon) {return mFileList.get(positon);}
}public class TextFile extends File {public TextFile(String name) {super(name);}@Overridepublic void Watch() {System.out.println("这是一个叫"+getName()+"的文件夹");}
}测试:
public static void main(String[] args){TextFile textFileA =new TextFile("a.txt");TextFile textFileB =new TextFile("b.txt");TextFile textFileC =new TextFile("c.txt");textFileA.Watch();Folder folder = new Folder("组合设计模式");folder.add(textFileA);folder.add(textFileB);folder.add(textFileC);folder.Watch();folder.getChild(1).Watch();}
优点:高层模块调用简单;节点自由增加,案例中创建了两个子类,可以创建多个子类;
缺点:违反了依赖倒置原则;
相关文章:
设计模式学习笔记--单例、建造者、适配器、装饰、外观、组合
以下内容根据以下网址及相关视频整理:Android设计模式之单例模式_谬谬清不给我取名字的博客-CSDN博客_android 单例模式 Android设计模式--单例模式的六种实现和单例模式讲解Volatile与Synchronized相关的并发_龙腾腾的博客-CSDN博客_android 单例 volatile java …...
English Learning - Day5 L1考前复习 2023.2.10 周五
English Learning - Day5 L1考前复习 2023.2.10 周五1 单选题:She has the face _________.2 单选题: The goals ________ he fought all his life no longer seemed important to him.3 单选题:Sales director is a position ______ communi…...
C. Prepend and Append
time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Timur initially had a binary string†† s� (possibly of length 00). He performed the following operation several (possibly zero)…...

javassm超市在线配送管理系统
为了解决用户便捷地在网上购物,本文设计和开发了一个超市管理系统。本系统是基于web架构设计,SSM框架 ,使用Mysql数据库管理,综合采用JSP模式来完成系统的相关功能。主要实现了管理员与用户的注册与登陆,个人中心、用户…...
Scratch少儿编程案例-多模式贪吃蛇(无尽和计时)
专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...

谷歌蜘蛛池怎么搭建?Google蜘蛛池可以帮助谷歌排名吗?
本文主要分享关于谷歌蜘蛛池的搭建疑问,以及Google对谷歌排名的影响到底有多大。 本文由光算创作,有可能会被剽窃和修改,我们佛系对待这种行为吧。 谷歌蜘蛛池怎么搭建? 答案是:需要一个内链外链体系复杂的站群系统…...

Kubernetes集群-部署Java项目
Kubernetes集群-部署Java项目(SSG) k8s部署项目java流程图 第一步 打包制作镜像 打包 java源码: application.properties #在有pom.xml的路径下执行 mvn clean package制作镜像: 将刚才打包后的文件夹传到,装有dock…...
English Learning - Day54 作业打卡 2023.2.8 周三
English Learning - Day54 作业打卡 2023.2.8 周三引言1. 就算你不喜欢喝酒,也请尝一杯吧。2. 便纵有千种风情,更与何人说?——柳永《雨霖铃》 (来,挑战一下古诗词)3. 虽然忙,我也要参加会议。4. 无论发生什么…...
【Unity题】 1.矩阵旋转,欧拉旋转,四元数旋转各自的优缺点。2.StringBuilder和String的区别
1.矩阵旋转,欧拉旋转,四元数旋转各自的优缺点 矩阵旋转,欧拉旋转,四元数旋转是三种不同的旋转表示方法,下面是它们各自的优缺点: 矩阵旋转: 优点: 1.可以方便地实现复合旋转&…...

【C++面试问答】搞清楚深拷贝与浅拷贝的区别
问题 深拷贝和浅拷贝的区别是面试中的常见问题之一,对于不同的编程语言,这个问题的回答可能稍有差别,下面我们就来探索一下它们之间的异同吧。 先来看看在JavaScript对象的深拷贝与浅拷贝的区别: 浅拷贝:只是复制了…...

day10_面向对象基础
今日内容 零、 复习昨日 一、面向对象的概念 二、面向对象编程 三、内存图 零、 复习昨日 见晨考题 每日一数组题 写一个方法 用于合并两个int类型的数组 合并法则如下 {1,2,5,8,9}{1,3,0}---->{1,2,5,8,9,1,3,0} package com.qf.array;import java.util.Arrays;/*** --- 天…...

电影订票网站的设计与开发
技术:Java、JSP等摘要:随着科技的发展,时代的进步,互联网已经成为了人们生活中不可缺少的一部分,网上购物已然是一种时代的象征。纵观市场,电影行业的发展尤为迅速,电影种类和数量的增多导致客流…...

seata【SAGA模式】代码实践(细节未必完全符合saga的配置,仅参考)
seata SAGA模式: 代码仍然是上一篇AT模式的代码:AT模式 不需要undo_log表 下面开始: 首先,saga模式依靠状态机的json文件来执行整个流程,其中的开始节点的服务即TM,然后状态机需要依靠三张表࿰…...

面试题:Java锁机制
java对象包含了三个部分:对象头,实例数据和对齐填充。对象头又存放了:markWord和class point。classpoint :指向方法区,当前对象的类信息数据。markword:存储了很多和当前对象运行时的数据:例如…...

Springboot Web开发
文章目录一. 静态资源访问1. 配置静态资源访问前缀2. 修改默认静态资源存放目录3. Webjars4. 欢迎页支持5. 自定义Favicon二. 请求处理1. 路径变量2. 请求头处理3. 查询字符串处理4. 获取Cookie的值5. 获取请求体的值6. 获取请求域中的数据7. 矩阵变量一. 静态资源访问 只要静…...

分布式事务 | 使用DTM 的Saga 模式
DTM 简介前面章节提及的MassTransit、dotnetcore/CAP都提供了分布式事务的处理能力,但也仅局限于Saga和本地消息表模式的实现。那有没有一个独立的分布式事务解决方案,涵盖多种分布式事务处理模式,如Saga、TCC、XA模式等。有,目前…...

错误代码0xc0000001要怎么解决?如何修复错误
出现错误代码0xc0000001这个要怎么解决?其实这个的蓝屏问题还是非常的简单的,有多种方法可以实现 解决方法一 1、首先使用电脑系统自带的修复功能,首先长按开机键强制电脑关机。 注:如果有重要的资料请先提前备份好,…...
为什么 HTTP PATCH 方法不是幂等的及其延伸
幂等性 首先来看什么是幂等性,根据 rfc2616(Hypertext Transfer Protocol – HTTP/1.1) 文档第 50 页底部对 Idempotent Methods 的定义: Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the…...

13 Day:实现内核线程
前言:我们昨天完成了内核的内存池以及内存管理程序,今天我们要揭开操作系统多任务执行的神秘面纱,来了解并实现一个多任务的操作系统。 一,实现内核线程 在聊线程之间我们先聊聊处理器吧,众所周之现在我们的CPU动不动…...

GPU服务器安装显卡驱动、CUDA和cuDNN
GPU服务器安装cuda和cudnn1. 服务器驱动安装2. cuda安装3. cudNN安装4. 安装docker环境5. 安装nvidia-docker25.1 ubuntu系统安装5.2 centos系统安装6. 测试docker容调用GPU服务1. 服务器驱动安装 显卡驱动下载地址https://www.nvidia.cn/Download/index.aspx?langcn显卡驱动…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...