设计模式、系统设计 record part04

news2024/11/26 19:19:07

结构型模式

在这里插入图片描述
结构型模式分为:
1.类结构型模式
2.对象结构型模式
3。类结构型,使用继承机制,耦合度高,不灵活
4.对象结构型,使用组合、聚合关系,耦合低,灵活


代理模式

在这里插入图片描述
1.代理就是中介
2.静态代理,在编译期生成,就是写代码的时候就存在了
3.动态代理,在Java运行时生成,执行代码时才有,
4.动态代理分为,JDK、CGLib 两种
CGLib(Code Generation Library) 代码生成库
在这里插入图片描述 1.真实主题 Real Subject,是最终要被引用的对象,就是给它做代理,> 代理类 Proxy ,在其内部引用真实主题 Real Subject,对 Real Subject 能看、能写
在这里插入图片描述

  1. 火车站、是真实主题 Real Subject,
    2.代理点,是代理,引用了火车站的功能,方法sell()卖票,
    3.代理点、火车站都要去实现接口SellTichets
    聚合关系用菱形表示,不是箭头,而且是空心菱形
    实验相关类,如下:
    在这里插入图片描述
    抽象主题类,接口 SellTickets,代码如下:
    在这里插入图片描述
    真实主题类 TrainStation,代码如下:
    在这里插入图片描述
    代理类 ProxyPoint ,代码如下:
    在这里插入图片描述
    可见,代理类 ProxyPoint 和 真实主题类 TrainStation,都去实现了 抽象主题类,接口 SellTickets,
    测试类 Client ,代码如下:
    在这里插入图片描述
    通过操作代理来间接的使用真实主题中的方法,
    也就是说,真实主题中的方法只允许代理来调用,所以要想使用真实主题中的方法,就必须通过代理来达成。
    运行结果,如下:
    在这里插入图片描述

JDK动态代理
在这里插入图片描述
.newProxyInstance()获取代理对象
相关实验包含的类,如下:
在这里插入图片描述
抽象主题,接口 SellTickets,代码如下:
在这里插入图片描述
真实主题 TrainStation,代码如下:
在这里插入图片描述
代理工厂 ProxyFactory,代码如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
October2024the06thSunday
1.
在这里插入图片描述
在这里插入图片描述
2.
在这里插入图片描述
在这里插入图片描述
3.
在这里插入图片描述
在这里插入图片描述
通过newProxyInstance()方法可以拿到类型是SellTickets接口的代理对象proxyObject代理对象,但newProxyInstance()方法里要传入参数 如上面描述的1、2、3,
代码如下:
在这里插入图片描述
测试类 Client,代码如下:
在这里插入图片描述
测试结果,如下:
在这里插入图片描述
通过反编译工具查看动态代理对象是如何实现的,底层代码,如下
在这里插入图片描述
使用反射机制拿到动态代理类的对象,其中使用到类的路径、方法,如下:
在这里插入图片描述

CGLIB 动态代理
在这里插入图片描述
1.JDK 动态代理,要求,必须定义,接口,
然后,才是对接口进行代理,
2,CGLIB 动态代理,为没有实现接口的类,
提供代理,对 JDK 动态代理进行了补充,
3.CGLIB 动态代理,是第三方包,需要引入jar包

两种动态代理方式的对比,如下:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
CGLIB 动态代理实验涉及的类,如下:
在这里插入图片描述
注意,这里已经不需要接口了,
其中的被代理类(目标类) TrainStation,代码如下:
在这里插入图片描述
代理类 ProxyFactory ,代码如下:
在这里插入图片描述
在这里插入图片描述
.create()方法会自动去调用 intercept()方法,
测试类 Clinet ,代码如下:
在这里插入图片描述
运行结果,如下:
在这里插入图片描述


适配器模式

在这里插入图片描述
在这里插入图片描述
分为 类适配器模式、对象适配器模式,
在这里插入图片描述
SDAdapterTF 通过继承关系,就获得了 TFCardImpl 中的关于TF相关的能力,
继承关系,使用实线+空心三角形表示,

类适配器实验,相关类和接口,如下:
在这里插入图片描述
有读取SD的需求,computer 类 代码如下,
在这里插入图片描述
适配者(Adaptee)SDCard ,它是接口,代码如下:
在这里插入图片描述
适配者(Adaptee)SDCard 的实现类 SDCardImpl ,如下:
在这里插入图片描述
目标接口( Target )TFCard 接口代码如下:
在这里插入图片描述
目标接口 TFCard 的实现类 TFCard Impl ,代码如下:
在这里插入图片描述
适配器 (Adapter)SDAdapterTF ,代码如下:
在这里插入图片描述
SDAdapterTF 既实现适配者 SDCard 接口, 又继承了 目标接口 TFCard 的实现类 TFCard Impl,所以它同时拥有两个接口的所有方法,这样就达到了适配的目的,即让使用者 computer 同时使用 SD、TF 2种卡。
注意,上图中适配器SDAdapterTF 使用的是适配者 SDCard 接口中的方法 readSD(),但在这个方法里却能调用目标接口 TFCard中的方法 readTF(),
原因就是,SDAdapterTF 既实现适配者 SDCard 接口, 又继承了 目标接口 TFCard 的实现类 TFCard Impl,
这里还有一个很巧妙的事情是,SDAdapterTF 实现适配者 SDCard 接口,它就可以被当作参数被传参进 使用者 computer 里,这样,
使用者computer 如果想用SD卡,就直接给自己传 适配者(Adaptee)SDCard 的实现类 SDCardImpl的对象,
在这里插入图片描述
如果要用TF卡,就给自己传适配器 (Adapter)SDAdapterTF的对象。
在这里插入图片描述
测试类 Client 代码如下:
在这里插入图片描述
测试结果,如下:
在这里插入图片描述

对象适配器实验,相关概念,如下:
在这里插入图片描述
空心菱形表示聚合关系,就是包含的关系,空心菱形指向适配器,说明 适配器 SDAdapterTF 包含 接口 TFCard,
两者的区别在于,类适配器,去继承TF的实现类,如下
在这里插入图片描述
对象适配器,与TF接口是聚合关系,如下
在这里插入图片描述
1.适配器多了一个属性,属性类型是TF接口,
2.适配器和TF接口之间是聚合关系,适配器 SDAdapterTF 包含 接口 TFCard
对象适配器实验,类和接口,如下
在这里插入图片描述
适配者(Adaptee),接口 SDCard ,代码如下:
在这里插入图片描述
SD卡的接口 SDCard 的接口实现类 SDCardImpl ,如下:
在这里插入图片描述
目标接口 TFCard ,代码如下:
在这里插入图片描述
目标接口 TFCard 的实现类 TFCardImpl ,代码如下
和类适配器中的对应代码大差不差
对象适配器 SDAdapterTF ,代码如下
在这里插入图片描述

在对象适配器 SDAdapterTF 类中组合一个目标接口 TFCard ,作为 SDAdapterTF 的属性,如下
在这里插入图片描述
接下来通过对象适配器 SDAdapterTF 类的构造方法,就能拿到
目标接口 TFCard 的对象,有了TFCard 的对象就能用TFCard 的对象中的方法了,同时,对象适配器 SDAdapterTF 本身又实现了适配者(Adaptee)接口 SDCard,所以,又可以使用接口 SDCard中的方法,
使用者 computer 类,代码如下
在这里插入图片描述
对应的测试类 Clinet,代码如下:
在这里插入图片描述
运行结果如下
在这里插入图片描述


装饰者模式

在这里插入图片描述
UML类图中空心三角形,表示继承,
上图中所有的类之间,存在的关系,都是继承关系
上图中的UML类图是一个存在问题(会产生过多的子类)的原始做法,待用装饰器模式进行改进,
在这里插入图片描述
用装饰器模式进行改进,UML类图,如下
在这里插入图片描述
空心菱形,是聚合关系,表示包含,上图中空心菱形的位置是错误的,它应该在Garnish类这边,因为空心菱形指向整体,而FastFood是被包含在Garnish中的,如下
在这里插入图片描述
所以,Garnish 是整体,它包含 FastFood,UML类图应该如下
在这里插入图片描述
装饰者模式实验中包含的类如下,
在这里插入图片描述
抽象构件(component)FastFood ,代码如下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
一个具体构件(concrete component)FriedRice,代码如下,
在这里插入图片描述
另一个具体构件(concrete component)FriedNoodles,代码如下,
在这里插入图片描述
抽象装饰(decorator)Garnish,代码如下
在这里插入图片描述
在这里插入图片描述
这里,可以看到上面代码中Garnish是FastFood的子类,所以有继承关系,
那么之前的图应该再改一下,如下,
在这里插入图片描述
两个方向上都应该有关系,
向左是子类Garnish继承父类FastFood,
向右是Garnish 聚合了 FastFood
Garnish 继承并聚合 FastFood
在这里插入图片描述
一个具体装饰(concrete decorator)Egg,代码如下:
在这里插入图片描述
这里有个难点 super(fastFood,price:1,desc:‘鸡蛋’),需要理解,Egg继承的Garnish,而Garnish就是装饰品,所以,Egg也是装饰品,
Egg这个构造方法产生的就是Egg的对象,所以,super(fastFoood,price:1,desc:‘鸡蛋’)这个对象就是Egg,至于Egg里面的三个参数中的 fastFood 就是 等待装饰品 Egg去修饰的 炒饭、炒面,
那么问题就来了,装饰品Egg里面除了自己的对象 Egg 还有个要被它所修饰的对象(炒米、炒面)
所以,装饰品Egg里的方法 cost()里面参与计算的有两个对象,
一个是 getPrice(),这个方法没有被其他东西所修饰,所以是Egg自己的方法,但在装饰品Egg里没有,所以需要到其父类也是个装饰品 Garnish 里找,发现也没有,所以继续向上,到Egg的爷爷(Garnish的父类)FastFood里去找,果然有, getPrice()返回的是 price,既然是装饰品Egg自己方法自然返回的就是Egg自己的price,而这个price在创建 Egg对象的时候,即 super(fastFood,price:1,desc:‘鸡蛋’)的时候就给了,因此,getPrice()得到的是对象Egg的price ,1
另一个参与计算的是,getFastFood().cost(),
因为getFastFood()前面也没有其他修饰词,所以它也是对象Egg的方法,但Egg里并没有这个方法,因此要到其父类Garnish里去找,能找到,这个方法返回的是 fastfood 对象,而这个 fastfood 对象,在创建Egg的时候也给了,即 super(fastFood,price:1,desc:‘鸡蛋’),也就是被装饰品Egg所修饰的炒饭对象、炒面对象,所以,getFastFood().cost()的cost()方法就是炒米对象、炒面对象的方法,得去炒米类、炒面类里去找,炒米类、炒面类里cost()方法,返回的是炒米类、炒面类的 getPrice()方法,也就是炒米类、炒面类的price,
特别提醒,
Egg对象的 cost()方法代码是:return getPrice()+getFastFood().cost(),
fastfood对象的cost()方法代码是:return getPrice()
Egg对象的 getPrice() 方法,在它爷爷 FastFood 类里,
fastfood对象 getPrice() 方法,在它爸爸 FastFood 类里,
Egg对象的price,在 new 鸡蛋的时候,即 super(fastfood ,price:1,desc:‘鸡蛋’)给出,
fastfood对象的price,在new 炒面、new 炒饭的时候,
即 super(price:12,desc:‘炒面’)、
super(price:10,desc:‘炒饭’)给出,
super关键字代表的就是“当前对象”的那部分父类型特征。
把 fastfood 对象作为Egg对象的属性,即 fastfood 对象当作它(Egg)的实例变量。
在这里插入图片描述> 一个具体装饰(concrete decorator)Bacon,代码如下:> 在这里插入图片描述
装饰者模式测试类 client ,代码如下:
在这里插入图片描述
运行结果如下:
在这里插入图片描述
注意,下面图片中的food,就是一个炒饭的对象,
在这里插入图片描述
而下面这个图片中有两个food,
在这里插入图片描述
括号里的food 是炒饭对象,而等号左边的food 是加了蛋的炒饭,即被蛋修饰的炒饭这个整体作为一个对象,自然它的价格price和描述就和单纯的炒饭不一样了,
再看下图,
在这里插入图片描述
红线上等号左边的food是第一次加蛋后的炒饭,这个对象,
被当成参数(也就是红圈里的food对象,)送给一个新new出来的Egg对象(红框里的food),
红框里的这个新的food对象,是加了两回蛋的炒饭,即被装饰器Egg修饰了2次,因此,它的price和desc都和单纯的没被修饰器修饰过的炒饭也不一样,和加了一个蛋的炒饭的price和desc也不一样,
最后,加了2个蛋的炒饭又被培根修饰了,如下图
在这里插入图片描述
所以最后得到的等号左边的food 是一个有两个鸡蛋和一个培根的炒饭,可以这么一直套下去,想用什么修饰器都可以一直往上加,这样通过Egg、Baken这样的修饰器给普通的FriedRice增加了新的功能,而且新功能可以一直往上加,得到多样化的结果,就像穿衣服一样,一件一件的套就完事了,

在这里插入图片描述
抽象构件(Componet):FastFood
抽象装饰(Decorator) :Garnish
具体构件(Concrete Component):FriedRice、FriedNoodles
具体装饰(Concrete Decorator) :Egg、Bacon
October2024the08thTuesday
在这里插入图片描述
上图说继承是静态的,指的是,父类一旦写好后,子类继承到的责任就都是固定好的了,这时就是固定的,静态的。
假如有需求要给某个子类增加责任,要么去修改父类让这个子类去继承(但是这样的话其他的子类也会受影响),要么修改这个子类让它自己往上加东西,然而不论怎样,都需要修改父子中的某一个,
而装饰者就很灵活了,需要啥就套啥,被装饰者需要啥,就把做好的带着啥的装饰器往被装饰者身上套就行了,这样就不需要去修改被装饰者以及被装饰者的父类了,而且是随便套,想怎么套就怎么套,这就动起来了,就好比身体是爸妈给的,缺气质就穿名牌,缺自信就戴金银,缺心眼就打唇钉……是动态的,


桥接模式

在这里插入图片描述
在这里插入图片描述
继承 change to 组合
在这里插入图片描述
桥接模式实验设计的类和接口,如下
在这里插入图片描述
一个具体实现化角色(concrete Implementor)AviFile ,代码如下:
在这里插入图片描述

一个实现化角色(Implementor) VideoFile接口,代码如下:
在这里插入图片描述
VideoFile接口,它就是一个桥梁,实现化角色用来连接具体实现化角色 and 扩展抽象化角色,
让扩展抽象化角色可以调用具体实现化角色中的业务方法
另一个具体实现化角色(concrete Implementor)RmvbFile ,代码如下:
在这里插入图片描述

一个抽象化角色(Abstraction),父类 OperatingSystem,代码如下:
在这里插入图片描述

一个扩展抽象化角色(Refined Abstraction),子类 Windows,代码如下:
在这里插入图片描述
另一个扩展抽象化角色(Refined Abstraction),子类 Mac,代码如下:
在这里插入图片描述
测试类 Client,代码如下:
在这里插入图片描述
测试结果,如下:
在这里插入图片描述
在这里插入图片描述


外观模式

在这里插入图片描述
在这里插入图片描述
迪米特法则(Law of Demeter )又叫做最少知识原则,也就是说,一个对象应当尽可能少的去了解(依赖)其他对象。尽可能不和陌生人说话。英文简写为: LoD。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扩展阅读:

1、门面模式:
为系统中的一组接口(多个子系统),向外提供一个统一的访问的入口,酒店服务的例子(客房、餐厅、洗衣)
银行柜台办理业务可以理解为门面模式的一种,客户通过银行柜台办理业务,无需了解银行内部复杂的业务逻辑处理,柜台是把银行能提供的业务展现给客户,银行没有提供的服务,柜台是无法办理。

1dvdplayer;
2soundsystem;
3screen;
4projector,
honetheaterFacade,1dvdplayer、2soundsystem、3screen、4projector 作为honetheaterFacade 的4个属性
通过honetheaterFacade 来统一调用 1dvdplayer、2soundsystem、3screen、4projector 的方法,
用户通过使用统一入口中的一个方法就可以同时调用多个子系统,而这个统一入口中的这个方法就提供了让统一入口去同时操作多个子系统的能力,因此无需用户再去分别与每个子系统都打一遍交道了,
大大简化了用户的操作,
适用于,简化复杂系统的使用,通过统一接口来操作复杂系统,
使得系统更易操作和维护

2、代理模式:
为了代理,房屋中介的例子,
代理模式比门面模式更高级
客户访问不到被代理对象,因此代理为客户(其他对象)提供一种访问、使用被代理对象的能力。这样客户可以通过代理对象间接的访问、使用被代理对象,

 interface door;
 labdoor implements door;
 securedoor implements door,labdoor 作为 securedoor 的一个属性
 new securedoor (new labdoor ());
通过使用代理 securedoor  ,来间接的访问操作 labdoor 
适用于,在访问对象时,需要做额外的操作,如权限控制
代理模式可以帮助你在不修改被代理对象的现有代码的情况下,实现对被代理对象的控制,
因为是通过代理来访问被代理对象的,所以能不能访问被代理对象都是代理说了算

3、适配器模式:
为了兼容,让两个不兼容的类可以协同一起工作,插座转换的例子、或翻译的例子
适配器模式比代理模式更复杂,
适配器模式(Adapter Pattern)
保持原有接口、功能和实现的同时,通过在适配器中包装一个不兼容的对象,来与另一个类兼容,
即,让现有类与其他类协同工作,而无需改变它们的源代码

interface mediaPlayer,有1个方法 play();
interface advancedMediaPlayer ,有2个方法 playVlc()、playAvi();
vlcPlayer implements advancedMediaPlayer ,有方法 playVlc();
aviPlayer implements advancedMediaPlayer,有方法 playAvi();
mediaAdapter implements mediaPlayer,
有两个属性 vlcMediaPlayer=new vlcPlayer() 、aviMediaPlayer=new aviPlayer();
videoPlayer implement mediaPlayer,获得一个适配器 mediaAdapter 
new mediaAdapter();
这样,videoPlayer 既可以使用原有接口mediaPlayer 的方法,又可以通过适配器 mediaAdapter 去调用接口 advancedMediaPlayer 的方法,从而达到 让原有接口 mediaPlayer  能支持 接口 advancedMediaPlayer,两者协同工作,
适配器 mediaAdapter 让原有接口 mediaPlayer 与接口 advancedMediaPlayer  ,协同工作,
注意,原有接口 mediaPlayer 是不支持 接口 advancedMediaPlayer 的,通过适配器 mediaAdapter将请求转发给接口 advancedMediaPlayer,让接口 mediaPlayer 获得了接口 advancedMediaPlayer 的能力,使得 原有接口 mediaPlayer  能支持 接口 advancedMediaPlayer 了。
适用于,现有类不支持其他类的时候,使用适配器让现有类能支持其他类,达到兼容的目的,

4、装饰器模式:
为了套娃,咖啡加奶的例子
装饰器模式(Decorator Pattern)
为对象动态地添加新的行为或责任
不改变对象代码的情况下为对象动态地添加新的职责或行为
咖啡加奶,不会改变咖啡的基本结构,但是会给咖啡增添柔和奶香的风味,

interface coffee;
simpleCoffee implements coffee;
espresso implements coffee;
coffeeDecorator implements coffee,有一个 coffee 类型的 属性 decoratedCoffee;
milkDecorator extends coffeeDecorator,其构造方法会产生一个coffee 类型的对象 ;
sugarDecorator extends coffeeDecorator,其构造方法会产生一个coffee 类型的对象 ;
new milkDecorator (new simpleCoffee ())
这样 milkDecorator 就可以修饰,通过自己构造函数获得的 coffee 类型的对象了 ,
同样 new sugarDecorator (new simpleCoffee ()), milkDecorator 也可以修饰,通过自己构造函数获得的 coffee 类型的对象了 
适用于,不需要修改原有对象的代码,就能动态的给原有对象添加新功能的场景,

各个模式之间的对比
适配器模式和装饰器模式的区别
虽然都是用于类的扩展和变换,但适配器模式更注重接口的转换和功能的实现;而装饰器模式则更注重对象的动态性在运行时动态地为对象添加新的职责或行为。

装饰器模式和代理模式的区别
装饰器模式给被装饰的对象增加功能,提供装饰功能,
代理模式不给对象增强功能,强调的是对一个对象的控制,提供代理功能

October2024the08thTuesday
补充
一个非常好的例子,关于适配器模式的实验代码,如下图
在这里插入图片描述

public interface TargetInterface {
void request(); }

public class Adaptee {
public void specificRequest() {
System.out.println(“Adaptee specific request.”); }
}

public class Adapter implements TargetInterface {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee; }
@Override
public void request() {
adaptee.specificRequest(); }
}

public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
TargetInterface target = new Adapter(adaptee);
target.request(); // 输出: Adaptee specific request.
} }

把上面的代码稍加修改,再放到可视化代码网站里去就能直接运行了,得到可视化代码图,能帮助很好的理解代码前后的关系,修改后的代码如下,


 interface TargetInterface{
   void request(); 
  }

 class Adaptee {
   public void specificRequest() {
     System.out.println("Adaptee specific request.");
    }
  }
 
 class Adapter implements TargetInterface {
   private Adaptee adaptee;
   public Adapter(Adaptee adaptee) {
     this.adaptee = adaptee; 
    }
   @Override
   public void request() {
     adaptee.specificRequest();
    } 
  }

 
 public class Client {
   public static void main(String[] args) {
     Adaptee adaptee = new Adaptee();
     TargetInterface target = new Adapter(adaptee);
     target.request();  // 输出: Adaptee specific request.
    }
  }

使用 Python Tutor: Visualize code 运行class Client得到最终结果,如下图
在这里插入图片描述
中间过程的可视化也很有意思,一并截取,如下:

过程1.如下:
在这里插入图片描述

过程2,如下:
在这里插入图片描述

过程3,如下:
在这里插入图片描述

过程4,如下:
在这里插入图片描述

过程5,如下:
在这里插入图片描述

最终结果,如下图
在这里插入图片描述

Python Tutor: Visualize code 可视化代码网址,如下:
https://pythontutor.com/render.html#mode=edit

October2024the08thTuesday

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

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

相关文章

64.DDR3读写控制器的设计与验证(1)(MIG IP核的配置)

(1)DRAM-动态随机存储器,SDRAM-同步动态随机存储器 DDR3 SDRAM- 第三代双倍速率同步动态随机存储器 双倍速率指的是时钟上升沿和下降沿都可以传输数据。同步指的是数据写入或读取时,是按时钟同步的。动态指的是硬件使用电容去存…

C# 自适应屏幕分辨率

一、新增AutoSizeFormClass.cs class AutoSizeFormClass{//(1).声明结构,只记录窗体和其控件的初始位置和大小。public struct controlRect{public int Left;public int Top;public int Width;public int Height;}//(2).声明 1个对象//注意这里不能使用控件列表记录 List nCtr…

云手机哪款好用?2024年云手机推荐对比指南

随着云手机市场的快速扩展,消费者在选择云手机时面临着众多选择。为了帮助大家找到最适合自己的云手机,小编特意整理了一份当前市场上几款备受关注的云手机品牌对比,大家一起往下看吧。 1. Ogphone云手机 Ogphone云手机是近年来海外业务版块迅…

图解C#高级教程(五):枚举器和迭代器

本章主要介绍 C# 当中枚举器、可枚举类型以及迭代器相关的知识。 文章目录 1. 枚举器和可枚举类型2. IEnumerator 和 IEnumerable 接口2.1 IEnumerator 接口2.2 IEnumerable 接口 3. 泛型枚举接口4. 迭代器4.1 使用迭代器创建枚举器4.2 使用迭代器创建可枚举类4.3 迭代器作为属…

谈论 MultiPHP

许多网站服务器提供商有大量客户,这些客户对他们的在线项目有各种需求。MultiPHP Manager界面可以帮助您轻松管理cPanel账户和域名的PHP和PHP-FPM配置,适用于运行EasyApache 4的系统。MultiPHP Manager界面提供了多种功能,包括: 服…

软考系统分析师知识点五:数据通信与计算机网络

前言 今年报考了11月份的软考高级:系统分析师。 考试时间为:11月9日。 倒计时:32天。 目标:优先应试,其次学习,再次实践。 复习计划第一阶段:扫平基础知识点,仅抽取有用信息&am…

安卓如何实现双击触摸唤醒点亮屏幕功能-源码分析linage os高通平台

背景: 前面文章已经有讲解过双击亮屏在一些方案调研情况,刚好linage os手机本身也有这个功能,刚好也有整体开源源码,所以今天带大家来对双击亮屏的源码部分进行剖析,本篇文章会一直分析到hal操作驱动节点。 设置作为…

有点晕,inline, crossinline,noinline小计

inline 主要用于展开铺平函数&#xff0c;用于高频访问但是代码不是很多的方法&#xff0c;减少函数对象的定义 fun <T> List<T>.normalForeach(action:(T)->Unit){for(item in this){action(item)} }inline fun <T> List<T>.inlinedForeach(action…

易图讯军用VR三维电子沙盘系统

深圳易图讯军用VR三维电子沙盘系统是一种集成了虚拟现实&#xff08;VR&#xff09;技术、三维建模技术、大数据分析、实时动态更新以及高度安全可靠的综合性军事指挥平台。该系统通过高精度三维模型真实再现战场环境&#xff0c;为指挥员提供沉浸式体验和交互操作的可能性&…

使用CANFD路由实现CAN与CANFD互通

随着科技的发展&#xff0c;汽车电子和工业领域中CAN通信需要承载数据量也越来越大&#xff0c;传统CAN通信有了向CANFD通信过渡的倾向。在实现过渡的过程中可能会出现自己设备是CAN通信&#xff0c;客户设备是CANFD通信的情况&#xff0c;或者自己设备是CANFD通信&#xff0c;…

react项目引入ant-design

当前react版本为&#xff1a; 1、安装antd npm install antd --save不需要安装babel-plugin-import&#xff0c;否则会报各种问题 2、引入Ant Design 样式 为了确保 Ant Design 样式在页面中生效&#xff0c;你需要在 _app.js 文件中全局引入样式。 当前项目用的Next.js。Ne…

vscode创建flutter项目,运行flutter项目

打开View&#xff08;查看&#xff09; > Command Palette...&#xff08;命令面板&#xff09;。 可以按下 Ctrl / Cmd Shift P 输入 flutter 选择Flutter: New Project 命令 按下 Enter 。选择Application 选择项目地址 输入项目名称 。按下 Enter 等待项目初始化完成 …

【HarmonyOS开发笔记 1】 -- 开发环境的搭建

DevEco Studio 的下载与安装 下载 下载路径&#xff1a; https://developer.huawei.com/consumer/cn/download/ 安装 解压后双击 deveco-studio-5.0.3.814.exe 指定安装目录&#xff0c;或者默认&#xff0c;然后下一步 一直“下一步”&#xff0c; 直到最后安装完成 新…

主机加固的关键要素:服务器防病毒

在数字化浪潮中&#xff0c;网络安全已成为企业不可忽视的一环。尤其是安全运维人员&#xff0c;他们肩负着保护企业数据不受侵害的重任。MCK主机加固解决方案&#xff0c;正是为了应对这一挑战而生。 网络安全的严峻现实 不久前&#xff0c;一家知名企业因勒索病毒攻击而被迫…

MVC、MVP和MVVM之间的区别

MVC&#xff08;Model-View-Controller&#xff09; 角色划分&#xff1a; Model&#xff1a;负责处理数据和业务逻辑&#xff0c;通常包括数据的存储、检索和更新等操作。 View&#xff1a;负责展示用户界面&#xff0c;接收用户输入&#xff0c;并将用户操作传递给 Controll…

如何在Visual Studio 2019中创建.Net Core WPF工程

如何在Visual Studio 2019中创建.Net Core WPF工程 打开Visual Studio 2019&#xff0c;选择Create a new project 选择WPF App(.Net Core) 输入项目名称和位置&#xff0c;单击Create 这样我们就创建好了一个WPF工程 工程文件说明 Dependencies 当前项目所使用的依赖库&…

java面向对之象类的继承与多态

目录 1.类的继承 图解 案例:创建一个动物类和一个猫类 1.代码 1)动物类 2)猫类 3.测试类 2.效果 2.父类方法的重写 案例:如何重写父类的方法 1.代码 1&#xff09;Animal类 2&#xff09;Dog类 3&#xff09;测试类 2.效果 3.super关键字 案例:如何在子类中调用父类的方…

如何使用 Puppeteer 和 Browserless 运行自动化测试?

Puppeteer&#xff1a;什么是 Puppeteer 及其功能 Puppeteer 是一个 Node.js 库。使用 Puppeteer&#xff0c;您可以在所有基于 Chromium 的浏览器上测试您的网站&#xff0c;包括 Chrome、Microsoft Edge Chrome 和 Chromium。此外&#xff0c;Puppeteer 可用于网页抓取、自动…

PDF处理技巧:Windows电脑如何选择合适的 PDF 编辑器

您可以阅读本文以了解用于在 PC 上编辑 PDF 的顶级免费软件&#xff0c;而无需花费任何费用即可轻松进行快速编辑、拆分、合并、注释、转换和共享您的 PDF。 PDF 或可移植文档文件是由 Adobe 创建的一种多功能文件格式。它可以帮助您轻松可靠地交换文档&#xff0c;无论相关方…

电脑端视频通过PCIE到FPGA端转UDP网络视频输出,基于XDMA+PHY芯片架构,提供3套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案我这里已有的以太网方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图电脑端视频PCIE视频采集QT上位机XDMA配置及使用XDMA中断模块FDMA图像缓存UDP视频组包发送UDP协议栈MAC数据缓冲FIFO组Tri Mode E…