我的理解:
代理模式,重要的是代理,怎么代理呢,在生活中比较显著的例子,就是律师给委托人,打官司,委托人提供事件的经过(起因,发展,结果),律师负责二次称述,在案件的基础上发表自己的建议
举个好玩的例子
我们想玩游戏,但又不想碰触到游戏中的烦恼,如何解决呢?有办法,现在游戏代练的公司非常多,我把自己的账号交给代练人员,由他们去帮我升级,去打怪,非常好的想法,我们看一下下类图
定义一个接口IGamePlayer,是所有喜爱网络游戏的玩家,然后定义一个具体
的实现类GamePlayer,实现每个游戏爱好者为了玩游戏要执行的功能,在类图中增加了一个GamePlayerProxy类来代表游戏代练者,它也不能有作弊的方法呀,游戏代练者也是手动打怪呀,因此同样继承IGamePlayer接口,
游戏者:代码
public class GamePlayer implements IGamePlayer {
private String name = "";
//通过构造函数传递名称
public GamePlayer(String _name){
this.name = _name;
}
//打怪,最期望的就是杀老怪
public void killBoss() {
System.out.println(this.name + "在打怪!");
}
//进游戏之前你肯定要登录吧,这是一个必要条件
public void login(String user, String password) {
System.out.println("登录名为"+user+"的用户"+this.name+"登录成功!");
}
//升级,升级有很多方法,花钱买是一种,做任务也是一种
public void upgrade() {
System.out.println(this.name + " 又升了一级!");
}
}
代练者 代码:
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
//通过构造函数传递要对谁进行代练
public GamePlayerProxy(IGamePlayer _gamePlayer){
this.gamePlayer = _gamePlayer;
}
//代练杀怪
public void killBoss() {
this.gamePlayer.killBoss();
}
//代练登录
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
//代练升级
public void upgrade() {
this.gamePlayer.upgrade();
}
}
通过构造方法去传递被代理的游戏玩家,让带练的玩家,打怪升级。
场景类:
public class Client {
public static void main(String[] args) {
//定义一个痴迷的玩家
IGamePlayer player = new GamePlayer("张三");
//然后再定义一个代练者
IGamePlayer proxy = new GamePlayerProxy(player);
//开始打游戏,记下时间戳
System.out.println("开始时间是:2009-8-25 10:45");
proxy.login("zhangSan", "password");
//开始杀怪
proxy.killBoss();
//升级
proxy.upgrade();
//记录结束游戏时间
System.out.println("结束时间是:2009-8-26 03:40");
}
}
结果是:
结果并没有改变,但是还是能打怪升级,你的游戏已经在升级,有人在帮你干活了!终于升级到120级,这就是代理模式
看一下通用的代理模式定义:为其他对象提供一种代理以控制对这个对象的访问
怎么理解呢,代理类,可以调用被代理类的方法,完成一系列的业务逻辑,控制被代理类
Subject抽象主题角色(游戏的接口)
抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
RealSubject具体主题角色(具体的玩家)
也叫做被委托角色、被代理角色。它才是冤大头,是业务逻辑的具体执行者。
Proxy代理主题角色(代练玩家)
也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制
委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
代理模式的优点
● 职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理
完成一件事务,附带的结果就是编程简洁清晰。
● 高扩展性
具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱
如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。
代理模式的使用场景
我们为啥要使用代理呢,
想想现实世界吧,打官司为什么要找个律师?因为你不想参与中间过程的是是非非,只要完成自己的答辩
就成,其他的比如事前调查、事后追查都由律师来搞定。
大家可以看看Spring AOP,这是一个非常典型的动态代理
接下来 代理模式的扩展,才是重点
代理模式的扩展
一类:普通代理(别代理者,必须知道谁代理它才可以完成代理)
首先说普通代理,它的要求就是客户端只能访问代理角色,而不能访问真实角色,这是
比较简单的。我们以上面的例子作为扩展,我自己作为一个游戏玩家,我肯定自己不练级
了,也就是场景类不能再直接new一个GamePlayer对象了,它必须由GamePlayerProxy来进行
模拟场景。
改动很小,仅仅修改了两个实现类的构造函数,GamePlayer的构造函数增加了
_gamePlayer参数,代理角色则只要传入代理者名字即可,而不需要说是替哪个对象做代
理。
普通代理的游戏者
普通代理的游戏者
public class GamePlayer implements IGamePlayer {
private String name = "";
//构造函数限制谁能创建对象,并同时传递姓名
public GamePlayer(IGamePlayer _gamePlayer,String _name) throws Exception{
if(_gamePlayer == null ){
throw new Exception("不能创建真实角色!");
}else{
this.name = _name;
}
}
//打怪,最期望的就是杀老怪
public void killBoss() {
System.out.println(this.name + "在打怪!");
}
//进游戏之前你肯定要登录吧,这是一个必要条件
public void login(String user, String password) {
System.out.println("登录名为"+user + "的用户" + this.name + "登录成功!");
}
//升级,升级有很多方法,花钱买是一种,做任务也是一种
public void upgrade() {
System.out.println(this.name + " 又升了一级!");
}
}
在构造函数中,传递进来一个IGamePlayer对象,检查谁能创建真实的角色,当然还可以
有其他的限制,比如类名必须为Proxy类等.
普通代理的代理者 GamePlayerProxy
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
//通过构造函数传递要对谁进行代练
public GamePlayerProxy(String name){
try {
gamePlayer = new GamePlayer(this,name);
} catch (Exception e) {
// TODO 异常处理
}
}
//代练杀怪
public void killBoss() {
this.gamePlayer.killBoss();
}
//代练登录
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
//代练升级
public void upgrade() {
this.gamePlayer.upgrade();
}
}
仅仅修改了构造函数,传递进来一个代理者名称,即可进行代理,在这种改造下,系统
更加简洁了,调用者只知道代理存在就可以,不用知道代理了谁
普通代理的场景类
public class Client {
public static void main(String[] args) {
//然后再定义一个代练者
IGamePlayer proxy = new GamePlayerProxy("张三");
//开始打游戏,记下时间戳
System.out.println("开始时间是:2009-8-25 10:45");
proxy.login("zhangSan", "password");
//开始杀怪
proxy.killBoss();
//升级
proxy.upgrade();
//记录结束游戏时间
System.out.println("结束时间是:2009-8-26 03:40");
}
}
运行结果完全相同。在该模式下,调用者只知代理而不用知道真实的角色是谁,屏蔽了
真实角色的变更对高层模块的影响,真实的主题角色想怎么修改就怎么修改,对高层次的模
块没有任何的影响,只要你实现了接口所对应的方法.
强制代理
一般的思维都是通过代理找到真实
的角色,但是强制代理却是要“强制”,你必须通过真实角色查找到代理角色,否则你不能访
问。甭管你是通过代理类还是通过直接new一个主题角色类,都不能访问,只有通过真实角
色指定的代理类才可以访问。
举个生活中的例子
这就好比是你和一个明星比较熟,相互认
识,有件事情你需要向她确认一下,于是你就直接拨通了明星的电话:
“喂,沙比呀,我要见一下×××导演,你帮下忙了!”
“不行呀衰哥,我这几天很忙呀,你找我的经纪人吧……”
郁闷了吧,你是想直接绕过她的代理,谁知道返回的还是她的代理,这就是强制代理,
你可以不用知道代理存在,但是你必须通过代理类提供,实例化对象,自己new都不行
在这里插入图片描述
强制代理的真实角色
public class GamePlayer implements IGamePlayer {
private String name = "";
//我的代理是谁
private IGamePlayer proxy = null;
public GamePlayer(String _name){
this.name = _name;
}
//找到自己的代理
public IGamePlayer getProxy(){
this.proxy = new GamePlayerProxy(this);
return this.proxy;
}
//打怪,最期望的就是杀老怪
public void killBoss() {
if(this.isProxy()){
System.out.println(this.name + "在打怪!");
}else{
System.out.println("请使用指定的代理访问");
}
}
//进游戏之前你肯定要登录吧,这是一个必要条件
public void login(String user, String password) {
if(this.isProxy()){
System.out.println("登录名为"+user+"的用户"+this.name+"登录成功!");
}else{
System.out.println("请使用指定的代理访问");;
}
}
//升级,升级有很多方法,花钱买是一种,做任务也是一种
public void upgrade() {
if(this.isProxy()){
System.out.println(this.name + " 又升了一级!");
}else{
System.out.println("请使用指定的代理访问");
}
}
//校验是否是代理访问
private boolean isProxy(){
if(this.proxy == null){
return false;
}else{
return true;
}
}
}
增加了一个私有方法,检查是否是自己指定的代理,是指定的代理则允许访问,否则不
允许访问。我们再来看代理角色,
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
//构造函数传递用户名
public GamePlayerProxy(IGamePlayer _gamePlayer){
this.gamePlayer = _gamePlayer;
}
//代练杀怪
public void killBoss() {
this.gamePlayer.killBoss();
}
//代练登录
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
//代练升级
public void upgrade() {
this.gamePlayer.upgrade();
}
//代理的代理暂时还没有,就是自己
public IGamePlayer getProxy(){
return this;
}
}
我们先按照常规的思路来运行一下,直接new一个真实角
色,如代码清单12-16所示。
public class Client {
public static void main(String[] args) {
//定义一个游戏的角色
IGamePlayer player = new GamePlayer("张三");
//开始打游戏,记下时间戳
System.out.println("开始时间是:2009-8-25 10:45");
player.login("zhangSan", "password");
//开始杀怪
player.killBoss();
//升级
player.upgrade();
//记录结束游戏时间
System.out.println("结束时间是:2009-8-26 03:40");
}
}
运行结果是,自己创建的都不行,必须是由代理者创建的
强制代理
public class Client {
public static void main(String[] args) {
//定义一个游戏的角色
IGamePlayer player = new GamePlayer("张三");
//获得指定的代理
IGamePlayer proxy = player.getProxy();
//开始打游戏,记下时间戳
System.out.println("开始时间是:2009-8-25 10:45");
proxy.login("zhangSan", "password");
//开始杀怪
proxy.killBoss();
//升级
proxy.upgrade();
//记录结束游戏时间
System.out.println("结束时间是:2009-8-26 03:40");
}
}
增加了一个IProxy接口,其作用是计算代理的费用。我们先来看IProxy接口,如代码清
单12-19所示。
代码清单12-19 代理类的接口
public interface IProxy {
//计算费用
public void count();
}
非常简单,看GamePlayerProxy带来的变化,如代码清单12-20所示。
public class GamePlayerProxy implements IGamePlayer,IProxy {
private IGamePlayer gamePlayer = null;
//通过构造函数传递要对谁进行代练
public GamePlayerProxy(IGamePlayer _gamePlayer){
this.gamePlayer = _gamePlayer;
}
//代练杀怪
public void killBoss() {
this.gamePlayer.killBoss();
}
//代练登录
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
//代练升级
public void upgrade() {
this.gamePlayer.upgrade();
this.count();
}
//计算费用
public void count(){
System.out.println("升级总费用是:150元");
}
}
实现了IProxy接口,同时在upgrade方法中调用该方法,完成费用结算,其他的类都没有
任何改动。
一个类可以实现多个接口,完成不同任务的整合。也就是说代理类不仅仅可以实现主题
接口,也可以实现其他接口完成不同的任务,而且代理的目的是在目标对象方法的基础上作
增强,这种增强的本质通常就是对目标对象的方法进行拦截和过滤。
代理类,只需要添加合适的接口,就可以给被代理的对象添加功能了
**
**
动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。
现在有一个非常流行的名称叫做面向横切面编程,也就是AOP(AspectOriented Programming),其核心就是采用了动态代理机制,既然这么重要,我们来看一看怎么实现的
在类图中增加了一个InvocationHandler接口和GamePlayIH类,作用就是产生一个对象的
代理对象,其中InvocationHandler是JDK提供的动态代理接口,对被代理类的方法进行代理。
我们来看程序,接口保持不变,实现类也没有变化,
代码清单12-21 动态代理类
public class GamePlayIH implements InvocationHandler {
//被代理者
Class cls =null;
//被代理的实例
Object obj = null;
//我要代理谁
public GamePlayIH(Object _obj){
this.obj = _obj;
}
//调用被代理的方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(this.obj, args);
return result;
}
}
其中invoke方法是接口InvocationHandler定义必须实现的,它完成对真实方法的调用。我
们来详细讲解一下InvocationHandler接口,动态代理是根据被代理的接口生成所有的方法,
也就是说给定一个接口。
动态代理会宣称“我已经实现该接口下的所有方法了”,那各位读者
想想看,动态代理怎么才能实现被代理接口中的方法呢?默认情况下所有的方法返回值都是
空的,是的,代理已经实现它了,但是没有任何的逻辑含义,那怎么办?好办,通过
InvocationHandler接口,所有方法都由该Handler来进行处理,即所有被代理的方法都由
InvocationHandler接管实际的处理任务。
我们接下来看看场景类,
public class Client {
public static void main(String[] args) throws Throwable {
//定义一个痴迷的玩家
IGamePlayer player = new GamePlayer("张三");
//定义一个handler
InvocationHandler handler = new GamePlayIH(player);
//开始打游戏,记下时间戳
System.out.println("开始时间是:2009-8-25 10:45");
//获得类的class loader
ClassLoader cl = player.getClass().getClassLoader();
//动态产生一个代理者
IGamePlayer proxy = (IGamePlayer)Proxy.newProxyInstance(cl,new Class[]{
IGamePlayer.class},handler);
//登录
proxy.login("zhangSan", "password");
//开始杀怪
proxy.killBoss();
//升级
proxy.upgrade();
//记录结束游戏时间
System.out.println("结束时间是:2009-8-26 03:40");
}
}
我们还是让代练者帮我们打游戏,但是我们既没有创建代理类,也没有实现IGamePlayer
接口,这就是动态代理。
,还有更重要的,如果想让
游戏登录后发一个信息给我们,防止账号被人盗用嘛,该怎么处理?直接修改被代理类
GamePlayer?这不是一个好办法,好办法如代码
public class GamePlayIH implements InvocationHandler {
//被代理者
Class cls =null;
//被代理的实例
Object obj = null;
//我要代理谁
public GamePlayIH(Object _obj){
this.obj = _obj;
}
//调用被代理的方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(this.obj, args);
//如果是登录方法,则发送信息
if(method.getName().equalsIgnoreCase("login")){
System.out.println("有人在用我的账号登录!");
}
return result;
}
}
只要在代理中增加一个判断就可以决定是否要发送信息,
有人用我的账号就发送一个信息,然后看看自己的账号是不是被人盗了,非常
好的方法,这就是AOP编程。AOP编程没有使用什么新的技术,但是它对我们的设计、编码
有非常大的影响,对于日志、事务、权限等都可以在系统设计阶段不用考虑,而在设计后通
过AOP的方式切过去。
类图如图
很简单,两条独立发展的线路。动态代理实现代理的职责,业务逻辑Subject实现相关的
逻辑功能,两者之间没有必然的相互耦合的关系。通知Advice从另一个切面切入,最终在高
层模块也就是Client进行耦合,完成逻辑的封装任务。我们先来看Subject接口,如代码清单
代码清单12-24 抽象主题
public interface Subject {
//业务操作
public void doSomething(String str);
}
其中的doSomething是一种标识方法,可以有多个逻辑处理方法,实现类如代码清单
public class RealSubject implements Subject {
//业务操作
public void doSomething(String str) {
System.out.println("do something!---->" + str);
}
}
重点是我们的MyInvocationHandler,如代码清单12-26所示
public class MyInvocationHandler implements InvocationHandler {
//被代理的对象
private Object target = null;
//通过构造函数传递一个对象
public MyInvocationHandler(Object _obj){
this.target = _obj;
}
//代理方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//执行被代理的方法
return method.invoke(this.target, args);
}
}
非常简单,所有通过动态代理实现的方法全部通过invoke方法调用。DynamicProxy代码
如代码清单12-27所示
7 动态代理类
public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){
//寻找JoinPoint连接点,AOP框架使用元数据定义
if(true){
//执行一个前置通知
(new BeforeAdvice()).exec();
}
//执行目标,并返回结果
return (T)Proxy.newProxyInstance(loader,interfaces, h);
}
}
在这里插入了较多的AOP术语,如在什么地方(连接点)执行什么行为(通知)。我们
在这里实现了一个简单的横切面编程,有经验的读者可以看看AOP的配置文件就会明白这段
代码的意义了。我们来看通知Advice,也就是我们要切入的类,接口和实现如代码清单12
public interface IAdvice {
//通知只有一个方法,执行即可
public void exec();
}
public class BeforeAdvice implements IAdvice{
public void exec(){
System.out.println("我是前置通知,我被执行了!");
}
}
动态代理的场景类
public class Client {
public static void main(String[] args) {
//定义一个主题
Subject subject = new RealSubject();
//定义一个Handler
InvocationHandler handler = new MyInvocationHandler(subject);
//定义主题的代理
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().
getClassLoader(), subject.getClass().getInterfaces(),handler);
//代理的行为
proxy.doSomething("Finish");
}
}
好,所有的程序都看完了,我们回过头来看看程序是怎么实现的。在DynamicProxy类
中,我们有这样的方法:
this.obj=Proxy.newProxyInstance(c.getClassLoader(),c.getInterfaces(),new MyInvocationHandler(_obj));
该方法是重新生成了一个对象,为什么要重新生成?你要使用代理呀,注意
c.getInterfaces()这句话,这是非常有意思的一句话,是说查找到该类的所有接口,然后实现
接口的所有方法。当然了,方法都是空的,由谁具体负责接管呢?是new
MyInvocationHandler(_Obj)这个对象。于是我们知道一个类的动态代理类是这样的一个类,
由InvocationHandler的实现类实现所有的方法,由其invoke方法接管所有方法的实现,其动态
调用过程如图12-9所示。
读者可能注意到我们以上的代码还有更进一步的扩展余地,注意看DynamicProxy类,它
是一个通用类,不具有业务意义,如果我们再产生一个实现类是不是就很有意义了呢?
public class SubjectDynamicProxy extends DynamicProxy{
public static <T> T newProxyInstance(Subject subject){
//获得ClassLoader
ClassLoader loader = subject.getClass().getClassLoader();
//获得接口数组
Class<?>[] classes = subject.getClass().getInterfaces();
//获得handler
InvocationHandler handler = new MyInvocationHandler(subject);
return newProxyInstance(loader, classes, handler);
}
}
场景类
public class Client {
public static void main(String[] args) {
//定义一个主题
Subject subject = new RealSubject();
//定义主题的代理
Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);
//代理的行为
proxy.doSomething("Finish");
}
}
友情提醒,在学习AOP框架时,弄清楚几个名词就成:切面(Aspect)、切入点
(JoinPoint)、通知(Advice)、织入(Weave)就足够了,理解了这几个名词,应用时你
就可以游刃有余了
文章浏览阅读725次。这个问题是在使用junit测试时出现的,就是需要关闭centos7的防火墙systemctl stop firewalld.service@SpringBootTest@RunWith(SpringRunner.class)public class TestFastDFS { //测试上传 @Test public void testUpdate() { ..._failed to connect to server connection timed out
文章浏览阅读250次。作为Rogério answered,在循环之外获取对象引用(Object object = example.getValue();)可能比在循环中调用getter更快(或至少不会更慢),因为在“最糟糕”的情况下,example.getValue()可能会在背景中做一些非常计算上昂贵的东西,尽管getter methods应该是“微不足道的”.通过分配引用一次并重新使用它,您只需执行一次昂贵的计算..._创建一个带局部变量的function java
文章浏览阅读1.9k次。题目:品尝饮料时间:2018-1-5一、要求1、使用命令行参数(饮料类型),输出该饮料类型的味道,如:当命令行参数为1时,结果见如下:咖啡:苦2、如果没有该种饮料,结果见如下:对不起!没有您输入的饮料类型。二、推荐实现步骤1、建立一个Java抽象类Drink,应当:a、声明一个抽象方法taste(),该方法负责输出饮料的味道;b、声明int型常量来代表不同的饮料类型(咖啡、啤酒、牛奶),如:1:咖..._三、品尝饮料 1.建立一个抽象类drink,应当: (1)声明一个抽象方法taste(),该方法负
文章浏览阅读618次。当我们做一个发送消息布局的时候,编辑框往往是在下面,而输入法弹出的时候就会吧编辑框完全遮挡,导致看不见输入框,这样用户体验就会很差!下面9种设置,可能会解决你在输入法上碰到的一些问题android:windowSoftInputMode=“adjustPan” 在Manifest.xml 属性一共有9个取值,分别是:stateUnspecified,stateUnchanged,stateHi..._stateunchanged
文章浏览阅读2.5k次。将电脑从以前版本的 Windows-如 Windows 7 或 Windows 8.1-升级到 Windows 10。本常见问题解答旨在解决有关升级到 Windows 10 的问题。本文将针对Win10的一些常见问题给出解决方案,如果你在使用Win10的过程中,遇到了无限重启、不能使用打印机和无法与Windows XP直接共享等问题,那这篇文章可能对你有帮助。升级win10出现的各种问题汇..._win10有问题
文章浏览阅读1k次。不同vlan间的通信简单配置1.单臂路由(图)环境:一台路由器,一台二层交换机,两台pc机二层交换机的配置一般模式:Switch>输入enable进入特权模式:Switch>enable输入configure terminal进入全局配置模式:Switch#configure terminalEnter configuration commands, one per line. En..._配置vlan使两台linux服务器互通
文章浏览阅读672次。android 源码编译后得到system.img,ramdisk.img,userdata.img映像文件。其中, ramdisk.img是emulator的 文件系统,system.img包括了主要的包、库等文件,userdata.img包括了一些用户数据,emulator负责加载这3个映像文件后,会 把system.img和userdata.img分别加载到 ramdisk文件系统中的sys..._android rootdir 编译到哪个镜像里
文章浏览阅读267次。当使用VS2013运行VS2010项目的时候,会提示升级VC++,点击确定但是运行调试的时候,还是会出错,找不到mfc100d.dll,msvcr100d.dll上网搜索,找办法安装XXX库之后,依旧不行**错误:**Building an MFC project for a non-Unicode character set is deprecated解决办法:微软解释用于多字节..._vs的unicode错误
文章浏览阅读142次。Dll在Windows下,DLL(Dynamic Link Library,动态链接库)是一个被编译过的二进制程序,但与.exe文件不同,.dll文件不能独立运行,必须由其他程序调用。为什么有这东西呢?当然有其存在的好处啦:不限语言。我们可以用自己熟悉的语言写DLL,然后由其他语言写的可执行程序来调用这些DLL。例如,可以用Python写程序的主界面,然后调用C写的实现一个具体功能的DLL模块。增..._automake,vs
文章浏览阅读5.1k次。1.1 unittest简介前言(python基础比较弱的,建议大家多花点时间把基础语法学好,这里有套视频,可以照着练习下:http://pan.baidu.com/s/1i44jZdb密码:92fs)熟悉java的应该都清楚常见的单元测试框架Junit和TestNG,这个招聘的需求上也是经常见到的。python里面也有单元测试框架-unittest,相当于是一个python版的junit。..._python+selenium+unittes分层
文章浏览阅读1w次,点赞14次,收藏70次。 PSIM是趋向于电力电子领域以及电机控制领域的仿真应用包软件。PSIM全称Power Simulation。PSIM是由SIMCAD 和SIMVIEM两个软件来组成的。 PSIM软件最大的特点是支持C语言模块,这样在仿真电路时,特别是数字电源或者电机驱动仿真时,可以直接编写C代码来驱动功率管,调试电路非常方便。 但是PSIM仿真软件在网上的教程比较少,学习起来比较困难,当时自己学习的时候也废了好大的功夫,于是决定写一个系列的文章,来比较全面的介绍一下PSIM软件的使用。由于自己也是刚学会不久,如_psim
文章浏览阅读238次。一般属性列表颜色常用判断格式:编辑属性 editableeditable=“bottom”是在行的底部创建2.editable=“top”是在行的顶部创建_"odoo editable=\"top"