23种设计模式:(二)结构型模式
根据北京尚学堂的视频所学习
结构型模式:
核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。
分类:
适配器模式、代理模式、桥接模式、 装饰模式、组合模式、外观模式、享元模式
结构型模式汇总
代理模式 | 为真实对象提供一个代理,从而控制对真实对象的访问 |
适配模式 | 使原本由于接口不兼容不能一起工作的类可以一起工作 |
桥接模式 |
处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继 承结构,使各个维度可以独立的扩展在抽象层建立关联。 |
组合模式 | 将对象组合成树状结构以表示”部分和整体”层次结构,使得客户可以统一的调用叶子对象和容器对象 |
装饰模式 | 动态地给一个对象添加额外的功能,比继承灵活 |
外观模式 | 为子系统提供统一的调用接口,使得子系统更加容易使用 |
享元模式 | 运用共享技术有效的实现管理大量细粒度对象,节省内存,提高效率• 生活中的场景 |
壹、适配器(adapter)模式
生活中的场景
什么是适配器模式?
– 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原 本由口不兼容而不能一起工于接作的那些类可以在一起工作。
• 模式中的角色
– 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象 的类,也可以是接口。
– 需要适配的类(Adaptee):需要适配的类或适配者类。
– 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成 目标接口。
/*** 需要被适配的类* @data :2019-6-1下午5:36:40* @author :田坤*/
public class Adaptee {public static void handleRe(){System.out.println("处理求情");}
}
/*** 目标接口* @data :2019-6-1下午5:47:56* @author :田坤*/
public interface Target {void handleRequest();
}
1、对象适配器
/*** 适配器(对象适配器)* @data :2019-6-1下午5:39:02* @author :田坤*/
public class Adapter implements Target{private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void handleRequest() {adaptee.handleRe();}
}
检测对象适配器
/*** 测试对象适配器* @data :2019-6-1下午5:45:08* @author :田坤*/
public class Test {public void test(Target t){t.handleRequest();}public static void main(String args[]) {Test test = new Test();Adaptee adaptee = new Adaptee();Adapter adapter = new Adapter(adaptee);test.test(adapter);}
}
2、类适配器
/*** 适配器(类适配器)* @data :2019-6-1下午5:39:02* @author :田坤*/
public class AdapterClass extends Adaptee implements Target{@Overridepublic void handleRequest() {handleRe();}
}
检测类适配器
/*** 测试类适配器* @data :2019-6-1下午5:45:08* @author :田坤*/
public class Test {public void test(Target t){t.handleRequest();}public static void main(String args[]) {Test test = new Test();Adaptee adaptee = new Adaptee();AdapterClass adapterClass = new AdapterClass();test.test(adapterClass);}
}
类图
工作中的场景
– 经常用来做旧系统改造和升级
– 如果我们的系统开发之后再也不需要维护,那么很多模式都是没必要的,但是不幸的是,事实却是维护一个系统的代价往往是开发一个系统的数倍。
我们学习中见过的场景
– java.io.InputStreamReader(InputStream)
– java.io.OutputStreamWriter(OutputStream)
贰、代理模式
核心作用:
通过代理,控制对对象的访问! 可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后 做后置处理。(即:AOP的微观实现!)
– AOP(Aspect Oriented Programming面向切面编程)的核心实现机制!
代理模式(Proxy pattern):
核心角色:
• 抽象角色
– 定义代理角色和真实角色的公共对外方法
• 真实角色
– 实现抽象角色,定义真实角色所要实现的业务逻辑, 供代理角色调用。
– 关注真正的业务逻辑!
• 代理角色
– 实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加 自己的操作。
– 将统一的流程控制放到代理角色中处理!
应用场景:
– 安全代理:屏蔽对真实角色的直接访问。
– 远程代理:通过代理类处理远程方法调用(RMI)
– 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。
比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时不可能将所有的图片都显示出来,这样就可以 使用代理模式,当需要查看图片时,用proxy来进行大图片的打开。
• 分类:
– 静态代理(静态定义代理类)
– 动态代理(动态生成代理类)
• JDK自带的动态代理
• javaassist字节码操作库实现
• CGLIB
• ASM(底层使用指令,可维护性较差)
1、静态代理(static proxy)
/*** 抽象对象* @data :2019-6-1下午6:25:19* @author :田坤*/
public interface Star {//面谈void confer();//签合同void signContract();//订票void bookTicket();//唱歌void sing();//收钱void collectMoney();
}
/*** 真实对象* @data :2019-6-1下午6:25:04* @author :田坤*/
public class RealStar implements Star {@Overridepublic void confer() {System.out.println("realstar-confer");}@Overridepublic void signContract() {System.out.println("realstar-signContract");}@Overridepublic void bookTicket() {System.out.println("realstar-bookTicket");}@Overridepublic void sing() {System.out.println("realstar(周杰伦)-Sing");}@Overridepublic void collectMoney() {System.out.println("realstar-collectMoney");}}
/*** 代理对象* @data :2019-6-1下午6:25:55* @author :田坤*/
public class ProxyStar implements Star{private RealStar realStar;public ProxyStar(RealStar realStar) {this.realStar = realStar;}@Overridepublic void confer() {System.out.println("confer");}@Overridepublic void signContract() {System.out.println("signContract");}@Overridepublic void bookTicket() {System.out.println("bookTicket");}@Overridepublic void sing() {realStar.sing();}@Overridepublic void collectMoney() {System.out.println("collectMoney");}}
/*** 检测静态代理* @data :2019-6-1下午6:30:31* @author :田坤*/
public class Test {public static void main(String args[]) {RealStar realStar = new RealStar();Star proxyStar = new ProxyStar(realStar);proxyStar.confer();proxyStar.signContract();proxyStar.bookTicket();proxyStar.sing();proxyStar.collectMoney();}
}
confer
signContract
bookTicket
realstar(周杰伦)-Sing
collectMoney
类图
2、动态代理(JDK自带的实现)
动态代理相比于静态代理的优点
–抽象角色中(接口)声明的所以方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和统一的处理众多的方法。
JDK自带的动态代理
– java.lang.reflect.Proxy
• 作用:动态生成代理类和对象
– java.lang.reflect.InvocationHandler(处理器接口)
• 可以通过invoke方法实现对真实角色的代理访问。
• 每次通过Proxy生成代理类对象对象时都要指定对应的处理器对象
/*** 抽象对象* @data :2019-6-1下午6:25:19* @author :田坤*/
public interface Star {//面谈void confer();//签合同void signContract();//订票void bookTicket();//唱歌void sing();//收钱void collectMoney();
}
/*** 真实对象* @data :2019-6-1下午6:25:04* @author :田坤*/
public class RealStar implements Star {@Overridepublic void confer() {System.out.println("realstar-confer");}@Overridepublic void signContract() {System.out.println("realstar-signContract");}@Overridepublic void bookTicket() {System.out.println("realstar-bookTicket");}@Overridepublic void sing() {System.out.println("realstar(周杰伦)-Sing");}@Overridepublic void collectMoney() {System.out.println("realstar-collectMoney");}}
/*** 对象处理器* @data :2019-6-1下午7:04:41* @author :田坤*/
public class StarHandler implements InvocationHandler{private Star realStar;public StarHandler(Star realStar) {this.realStar = realStar;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object obj = null;System.out.println("真正的执行流程");System.out.println("面谈,签合同,预付款,订机票");if(method.getName().equals("sing")){obj = method.invoke(realStar, args);}System.out.println("真正的方法执行后");System.out.println("收尾款");return obj;}}
/*** 检测动态代理(JDK自带)* @data :2019-6-1下午7:05:22* @author :田坤*/
public class Test0 {public static void main(String args[]) {Star realStar = new RealStar();StarHandler handler = new StarHandler(realStar);Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),newClass[]{Star.class},handler);proxy.sing();}
}
真正的执行流程
面谈,签合同,预付款,订机票
realstar(周杰伦)-Sing
真正的方法执行后
收尾款
模拟动态内部调用过程
开发框架中应用场景:
– struts2中拦截器的实现
– 数据库连接池关闭处理
– Hibernate中延时加载的实现
– mybatis中实现拦截器插件
– AspectJ的实现
– spring中AOP的实现
• 日志拦截
• 声明式事务处理
– web service
– RMI远程方法调用
– ...
– 实际上,随便选择一个技术框架都会用到代理模式!!
叁、桥接模式(Bridge)
• 场景分析
– 商城系统中常见的商品分类,以电脑为类,如何良好的处理商品分类销售的问题?
– 这个场景中有两个变化的维度:电脑类型、电脑品牌。
桥接模式核心要点:
– 处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立 的继承结构,使各个维度可以独立的扩展在抽象层建立关联。
肆、组合模式(composite)
使用组合模式的场景:
把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对 象和整体对象。
组合模式核心:
– 抽象构件(Component)角色: 定义了叶子和容器构件的共同点
– 叶子(Leaf)构件角色:无子节点
– 容器(Composite)构件角色: 有容器特征,可以包含子节点
组合模式工作流程分析:
– 组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组 合,使得用户在使用时可以一致性的对待容器和叶子。
– 当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员, 并调用执行。其中,使用了递归调用的机制对整个结构进行处理。
使用组合模式,模拟杀毒软件架构设计
package com.tk.composite;import java.util.ArrayList;
import java.util.List;/*** 抽象组件构建* @author 84741**/
public interface AbstractFile {void KillVirus(); //杀毒
}/*** 文件(叶子)*/
class Imgaefile implements AbstractFile{private String name;public Imgaefile(String name) {super();this.name = name;}@Overridepublic void KillVirus() {System.out.println("对图片文件"+name+"进行杀毒");}
}class Vodiofile implements AbstractFile{private String name;public Vodiofile(String name) {super();this.name = name;}@Overridepublic void KillVirus() {System.out.println("对影像文件"+name+"进行杀毒");}
}class Textfile implements AbstractFile{private String name;public Textfile(String name) {super();this.name = name;}@Overridepublic void KillVirus() {System.out.println("对文本文件"+name+"进行杀毒");}
}/*** 文件夹(容器)* @author 田坤* @time 2019年6月11日 上午8:43:51*/
class Folder implements AbstractFile{private String name;private List<AbstractFile> children = new ArrayList<AbstractFile>();public Folder(String name) {super();this.name = name;}public void add(AbstractFile af) {if(af!=null)children.add(af);}public void remove(AbstractFile af) {if(af!=null)children.remove(af);}public AbstractFile get(int i) {return children.get(i);}@Overridepublic void KillVirus() {System.out.println("正在处理"+name+"文件夹.......");for (AbstractFile abstractFile : children) {abstractFile.KillVirus();}}}
测试类
package com.tk.composite;public class Test {public static void main(String[] args) {AbstractFile f1,f2;f1 = new Textfile("hello.txt");f2 = new Vodiofile("lol比赛");Folder folder = new Folder("我的收藏");folder.add(f1);folder.add(f2);AbstractFile f3,f4;f3 = new Vodiofile("rngS9夺冠");f4 = new Imgaefile("s9RNG 捧杯");Folder folder2 = new Folder("S9圆梦");folder2.add(f3);folder2.add(f4);folder.add(folder2);folder.KillVirus();a}
}
正在处理我的收藏文件夹.......
对文本文件hello.txt进行杀毒
对影像文件lol比赛进行杀毒
正在处理S9圆梦文件夹.......
对影像文件rngS9夺冠进行杀毒
对图片文件s9RNG 捧杯进行杀毒
• 开发中的应用场景:
– 操作系统的资源管理器
– GUI中的容器层次图
– XML文件解析
– OA系统中,组织结构的处理
– Junit单元测试框架
• 底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(容器) 、Test接口(抽象)
• Junit单元测试框架底层设计
底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(容器) 、Test接口(抽象)
伍、装饰(器)模式(decoractor)
职责:
- 动态的为一个对象增加新的功能
- 装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀
实现细节:
– Component抽象构件角色:
• 真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
– ConcreteComponent 具体构件角色(真实对象):
• io流中的FileInputStream、FileOutputStream
– Decorator装饰角色:
• 持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象这样,就能在真实对象调用前后增加新的功能。
– ConcreteDecorator具体装饰角色:
• 负责给构件对象增加新的责任。
//– Component抽象构件角色:
public interface ICar {void move();
}//– ConcreteComponent 具体构件角色(真实对象):class Car implements ICar {@Overridepublic void move() {System.out.println("在陆地上移动");}
}//– Decorator装饰角色:
class SuperCar implements ICar{protected ICar car;public SuperCar(ICar car) {super();this.car = car;}@Overridepublic void move() {car.move();}
}//– ConcreteDecorator具体装饰角色:
class AICar extends SuperCar{public AICar(ICar car) {super(car);}public void autoMove() {System.out.println("自动跑");} public void move() {super.move();autoMove();}
}//– ConcreteDecorator具体装饰角色:
class WaterCar extends SuperCar{public WaterCar(ICar car) {super(car);}public void WaterMove() {System.out.println("水上跑");} public void move() {super.move();WaterMove();}
}//– ConcreteDecorator具体装饰角色:
class FlyCar extends SuperCar{public FlyCar(ICar car) {super(car);}public void FlyMove() {System.out.println("天上飞");} public void move() {super.move();FlyMove();}
}
测试类
public class Test {public static void main(String[] args) {Car car = new Car();car.move();System.out.println("添加水上跑功能.......");WaterCar water = new WaterCar(car);water.move();System.out.println("添加天上飞和自动跑功能......");FlyCar fly_anto = new FlyCar(new AICar(car));fly_anto.move();}
}
在陆地上移动
添加水上跑功能.......
在陆地上移动
水上跑
添加天上飞和自动跑功能......
在陆地上移动
自动跑
天上飞
• 开发中使用的场景:
– IO中输入流和输出流的设计
– Swing包中图形界面构件功能
– Servlet API 中提供了一个request对象的Decorator设计模式的默认实 现类HttpServletRequestWrapper,HttpServletRequestWrapper 类,增强了request对象的功能。
– Struts2中,request,response,session对象的处理
IO流实现细节:
– Component抽象构件角色:
• io流中的InputStream、OutputStream、Reader、Writer
– ConcreteComponent 具体构件角色:
• io流中的FileInputStream、FileOutputStream
– Decorator装饰角色:
• 持有一个抽象构件的引用:io流中的FilterInputStream、FilterOutputStream
– ConcreteDecorator具体装饰角色:
• 负责给构件对象增加新的责任。Io流中的BufferedOutputStream、BufferedInputStream等。
总结:
– 装饰模式(Decorator)也叫包装器模式(Wrapper)
– 装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并 使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新 的具体构建类和具体装饰类。
优点:
– 扩展对象功能,比继承灵活,不会导致类个数急剧增加
– 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更 加强大的对象
– 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加 新的具体构件子类和具体装饰子类。
缺点:
– 产生很多小对象。大量小对象占据内存,一定程度上影响性能。
– 装饰模式易于出错,调试排查比较麻烦。
陆、外观模式(dacade)
迪米特法则(最少知识原则):
– 一个软件实体应当尽可能少的与其他实体发生相互作用。
外观模式核心:
– 为子系统提供统一的入口。封装子系统的复杂性,便于客户端调用。
案例(类图)
– 注册公司流程(不使用外观模式)
注册公司流程(使用外观模式)
柒、享元模式
• 场景:
– 内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的 对象,我们可以通过享元模式,节省内存。
• 核心:
– 享元模式以共享的方式高效地支持大量细粒度对象的重用。
– 享元对象能做到共享的关键是区分了内部状态和外部状态。
• 内部状态:可以共享,不会随环境变化而改变
• 外部状态:不可以共享,会随环境变化而改变
• 享元模式实现:
– FlyweightFactory享元工厂类
• 创建并管理享元对象,享元池一般设计成键值对
– FlyWeight抽象享元类
• 通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象 的内部状态,设置外部状态。
– ConcreteFlyWeight具体享元类
• 为内部状态提供成员变量进行存储
– UnsharedConcreteFlyWeight非共享享元类
• 不能被共享的子类可以设计为非共享享元类
/*** 享元类* @author 田坤* @time 2019年6月11日 上午10:45:25*/
public interface ChessFlyWeight {void setColor(String color);String getColor();void display(coordinate c);
}// – ConcreteFlyWeight具体享元类
class ConcreteChess implements ChessFlyWeight{private String color;public ConcreteChess(String color) {super();this.color = color;}@Overridepublic void setColor(String color) {this.color = color;}@Overridepublic String getColor() {return color;}@Overridepublic void display(coordinate c) {System.out.println("该棋子的颜色:"+getColor());System.out.println("该棋子的坐标:"+c.getX()+"--"+c.getY());}}
/*** 外部状态 UnsharedConcrete* @author 田坤* @time 2019年6月11日 上午10:42:31*/
public class coordinate {private int x,y;public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public coordinate(int x, int y) {super();this.x = x;this.y = y;}public coordinate() {super();}@Overridepublic String toString() {return "coordinate [x=" + x + ", y=" + y + "]";}
}
/*** 享元工厂类* @author 田坤* @time 2019年6月11日 上午10:53:18*/
public class ChessFlyWeightFactory {//享元池private static Map<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();public static ChessFlyWeight getChess(String color) {if(map.get(color)!=null)return map.get(color);else {ChessFlyWeight chessFlyWeight = new ConcreteChess(color);map.put(color, chessFlyWeight);return chessFlyWeight;}}
}
测试类
public class Test {public static void main(String[] args) {ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");System.out.println(chess1);System.out.println(chess2);ChessFlyWeightFactory.getChess("黑色").display(new coordinate(10, 20));ChessFlyWeightFactory.getChess("黑色").display(new coordinate(20, 20));}
}
com.tk.hengyuan.ConcreteChess@4f19c297
com.tk.hengyuan.ConcreteChess@4f19c297
该棋子的颜色:黑色
该棋子的坐标:10--20
该棋子的颜色:黑色
该棋子的坐标:20--20
享元模式开发中应用的场景:
– 享元模式由于其共享的特性,可以在任何“池”中操作,
比如:线程池、数据库连接池。
– String类的设计也是享元模式
• 优点
– 极大减少内存中对象的数量
– 相同或相似对象内存中只存一份,极大的节约资源,提高系统性能
– 外部状态相对独立,不影响内部状态
• 缺点
– 模式较复杂,使程序逻辑复杂化
– 为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态 使运行时间变长。用时间换取了空间。
结构型模式汇总
代理模式 |
为真实对象提供一个代理,从而控制对真实对象的访问 |
适配模式 |
使原本由于接口不兼容不能一起工作的类可以一起工作 |
桥接模式 |
处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继 承结构,使各个维度可以独立的扩展在抽象层建立关联。 |
组合模式 |
将对象组合成树状结构以表示”部分和整体”层次结构,使得客户可以统一 的调用叶子对象和容器对象 |
装饰模式 |
动态地给一个对象添加额外的功能,比继承灵活 |
外观模式 |
为子系统提供统一的调用接口,使得子系统更加容易使用 |
享元模式 |
运用共享技术有效的实现管理大量细粒度对象,节省内存,提高效率 |
23种设计模式:(二)结构型模式相关推荐
- 备战面试日记(3.3) - (设计模式.23种设计模式之结构型模式)
本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.9 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...
- Java经典23种设计模式之结构型模式(二)
接上篇,本文介绍结构型模式里的组合模式.装饰模式.外观模式. 一.组合模式(Composite) 组合模式:将对象组合成树形结构,表示"部分--整体"的层次结构.最终达到单个对象和 ...
- JAVA23种设计模式(2)-结构型模式7种
JAVA23种设计模式(2)-结构型模式7种 把类结合在一起形成更大的结构 适配器模式(adapter) 一句话:将一个类的接口转换成另一种接口.让原本接口不兼容的类可以兼容 这是平时比较常见的一种模 ...
- Java23种设计模式——11.结构型模式之享元模式
Java中除去有设计原则之外,还有23中设计模式. 这些模式都是前辈们一点一点积累下来,一直在改进,一直在优化的,而这些设计模式可以解决一些特定的问题. 并且在这些模式中,可以说是将语言的使用体现的淋 ...
- Java中的23个设计模式 【结构型模式】 中的 【享元模式】
文章目录 设计模式分类 享元模式(FlyWeight) 介绍 案例--围棋软件设计 享元模式实现 开发中的应用场景 优缺点 优点 缺点 代码 抽象享元类 具体享元类,设置内部状态 非共享享元类,设置外 ...
- 设计模式二:结构型模式
一.适配器模式 将一个类的接口转换成客户希望的另一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 角色: 目标接口(Target) 待适配的类(Adaptee) 适配器( ...
- 备战面试日记(3.4) - (设计模式.23种设计模式之行为型模式)
本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.12 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文 ...
- 备战面试日记(3.2) - (设计模式.23种设计模式之创建型模式)
本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.6 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...
- 设计模式之结构型模式(5种)
目录 结构型模式(Structural Pattern):怎么构造一个对象(行为.属性) 一.适配器模式 二.桥接模式(Bridge) 三.装饰者模式 设计模式在JAVA I/O库中的应用 案例 使用 ...
- 设计模式_结构型模式学习
其中,单例模式用来创建全局唯一的对象.工厂模式用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象.建造者模式是用来创建复杂对象,可以通过设置不同的可 ...
最新文章
- 面试java回答优缺点_阿里Java开发面经分享,面试题(附回答)
- 常州大学 计算机与人工智能学院,第一届计算机视觉青年学者论坛(CVYSF)在常州大学举办...
- spec linux,linux – 在RPM包中SPEC文件中1%{?dist}的含义是什么?
- Nginx使用brotli代替gzip
- 西北师范大学地理与环境科学学院考研真题汇总(高等数学)持续更新。。。
- 男人必读:女人64个谜团
- SpringMVC框架----SessionAttribute注解
- SQL 全文索引 CONTAINS
- 关闭rhel 6.5的selinux
- Python DearPyGui 常用控件一
- xamarin.android searchview的一些用法
- octave c++函数中调用fortran77子程序
- php中怎么创建对象,php创建对象有哪几种方法
- 毕设题目:Matlab图像加密
- python deap_在Python中用DEAP绘制多目标pareto边界
- 中国最好的产品经理100人
- 澳洲那个大学计算机专业好,澳洲哪个大学计算机专业比较好
- 简化预测集合的永磁同步电机的无差拍预测转矩控制系统Simulink仿真
- YB1205B 外置MOS异步升压恒流LED驱动控制器
- aptio2018设置u盘启动_2018年U盘装系统bios设置U盘启动方法介绍
热门文章
- BIOS 启动类型:Legacy+UEFI、UEFI BOOT、Legacy BOOT
- 用计算机弹钢琴谱,flash用键盘弹钢琴,电脑钢琴谱-走啦网
- CTF show 萌新区解题报告 (二)
- IIS6 + Resin3.1.x 的不爽之处
- 计算机玩游戏不能全屏,电脑玩游戏为何不能全屏?电脑玩游戏不能全屏的解决方法...
- SQL必知必会第4版读书笔记
- object-c的存取权限(public/protected/private)
- apk 路由器劫持_各种路由器固件劫持方法(待完善)
- 关于斐讯K2路由器 j.s9w.cc 劫持的问题。
- 学术资源不定期分享-【费曼物理学讲义英文原版】