当前位置: 首页 > 编程日记 > 正文

职责链模式(Chain of Responsibility)(对象行为型)

1.概述

你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就推卸给另外个一个部门(对象)。至于到底谁来解决这个问题呢?政府部门就是为了可以避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,并且沿着这条链传递请求,直到有(部门)对象处理它为止。

2.问题

如果有多个对象都有可能接受请求,如何避免避免请求发送者与接收者耦合在一起呢?

3.解决方案

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。(Avoid coupling the sender of a request to itsreceiver by giving morethan one objecta chance to handle the request.Chain the receiving objects andpassthe request along the chain until an object handles it. )

1)在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
2)请求在这条链上传递,直到链上的某一个对象处理此请求为止。
3)发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。

4.适用性

在以下条件下使用Responsibility 链:

• 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。

• 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

•可动态指定一组对象处理请求。

5.结构

一个典型的对象结构可能如下图所示:

6. 模式的组成

抽象处理者角色(Handler:Approver):定义一个处理请求的接口,和一个后继连接(可选)

具体处理者角色(ConcreteHandler:President):处理它所负责的请求,可以访问后继者,如果可以处理请求则处理,否则将该请求转给他的后继者。

客户类(Client):向一个链上的具体处理者ConcreteHandler对象提交请求。

7. 效果

Responsibility 链有下列优点和缺点( l i a b i l i t i e s ) :

职责链模式的优点:

1 ) 降低耦合度 :该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求会被“正确”地处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需知道链的结构。

2) 职责链可简化对象的相互连接 :    结果是,职责链可简化对象的相互连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。

3) 增强了给对象指派职责( R e s p o n s i b i l i t y )的灵活性 :当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。

4)增加新的请求处理类很方便

职责链模式的缺点:
1) • 不能保证请求一定被接收。既然一个请求没有明确的接收者,那么就不能保证它一定会被处理 —该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。
2) • 系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
8. 纯与不纯的职责链模式
纯的职责链模式:一个具体处理者角色处理只能对请求作出两种行为中的一个:一个是自己处理(承担责任),另一个是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又将责任向下传的情况。请求在责任链中必须被处理,不能出现无果而终的结局。
反之就是不纯的职责链模式。
在一个纯的职责链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的职责链模式里面,一个请求可以最终不被任何接收端对象所接收。

9.实现

我们先来看不纯的职责模式:

假如在公司里,

如果你的请假时间小于0.5天,那么只需要向leader打声招呼就OK了。
如果0.5<请假天数<=3天,需要先leader打声招呼,要不然leader不知你跑哪里,然后部门经理直接签字。
如果3<请假天数 天,需要先leader打声招呼,然后到部门经理签字,最好总经经理确认签字,

当你看到这情况后你心里是不是已经有了自己的想法了?写一系列的if语句来一条条的判断.但这样的写法虽然可以实现目前的需求,可如果当流程改了呢?我请假超过3天,告诉leader和总经理签字就可以,那你又得一步一步修改程序。如果if语句的条数发生变化的话我们还必须在代码中添加必要的if判断,这对于程序的维护来说是相当麻烦的.如果我们使用职责链模式的话就可以相当简单了.

这个例子就是个list。也是个不纯的职责链,因为每个对象可能处理一部分后,就需要传给下个对象来处理。

  1. <?php
  2. /** 
  3.  * 加入在公司里,如果你的请假时间小于0.5天,那么只需要向leader打声招呼就OK了。 
  4.   如果0.5<请假天数<=3天,需要先leader打声招呼,要不然leader不知你跑哪里,然后部门经理直接签字。 
  5.   如果3<请假天数 天,需要先leader打声招呼,然后到部门经理签字,最好总经经理确认签字, 
  6.   这样就是个list。也是个不纯的职责链,因为每个对象可能处理一部分后,就需要传给下个对象来处理。 
  7.    
  8.  */  
  9. /** 
  10. * 纯职责链模式  
  11. *  
  12. * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它  
  13. * @author guisu 
  14. *  
  15. */   
  16. /** 
  17.  * 抽象处理者角色(Handler:Approver):定义一个处理请求的接口,和一个后继连接(可选) 
  18.  * 
  19.  */  
  20. abstract class Handler  
  21. {
  22. protected $_handler = null;  
  23. protected $_handlerName = null;  
  24. public function setSuccessor($handler)  
  25. {
  26. $this->_handler = $handler;  
  27. }
  28. protected  function _success($request)  
  29. {
  30. echo $request->getName(), '\' request was passed  <br/>';  
  31. return true;  
  32. }
  33. abstract function handleRequest($request);  
  34. }
  35. /** 
  36.  * 具体处理者角色(ConcreteHandler:President):处理它所负责的请求,可以访问后继者,如果可以处理请求则处理,否则将该请求转给他的后继者。 
  37.  * 
  38.  */  
  39. class ConcreteHandlerLeader extends Handler  
  40. {
  41. function __construct($handlerName){  
  42. $this->_handlerName = $handlerName;  
  43. }
  44. public function handleRequest($request)  
  45. {
  46. echo $this->_handlerName, ' was known <br/>';//已经跟leader招呼了  
  47. if($request->getDay() < 0.5) {  
  48. return $this->_success($request);  
  49. }
  50. if ($this->_handler instanceof Handler) {  
  51. return $this->_handler->handleRequest($request);  
  52. }
  53. }
  54. }
  55. /** 
  56.  * Manager 
  57.  * 
  58.  */  
  59. class ConcreteHandlerManager extends Handler  
  60. {
  61. function __construct($handlerName){  
  62. $this->_handlerName = $handlerName;  
  63. }
  64. public function handleRequest($request)  
  65. {
  66. echo $this->_handlerName, " was signed <br/>";//部门经理签字  
  67. if( $request->getDay() > 0.5 && $request->getDay()<=3) {  
  68. return $this->_success($request);  
  69. }
  70. if ($this->_handler instanceof Handler) {  
  71. return $this->_handler->handleRequest($request);  
  72. }
  73. }
  74. }
  75. class ConcreteHandlerGeneralManager extends Handler  
  76. {
  77. function __construct($handlerName){  
  78. $this->_handlerName = $handlerName;  
  79. }
  80. public function handleRequest($request)  
  81. {
  82. echo $this->_handlerName, " was signed <br/>";//总经理签字  
  83. if(3 < $request->getDay()){  
  84. return $this->_success($request);  
  85. }
  86. if ($this->_handler instanceof Handler) {  
  87. return $this->_handler->handleRequest($request);  
  88. }
  89. }
  90. }
  91. /** 
  92.  * 请假申请 
  93.  * 
  94.  */  
  95. class   Request  
  96. {
  97. private $_name;  
  98. private $_day;  
  99. private $_reason;  
  100. function __construct($name= '', $day= 0, $reason = ''){  
  101. $this->_name = $name;  
  102. $this->_day = $day;  
  103. $this->_reason = $reason;  
  104. }
  105. public function setName($name){  
  106. $this->_name = $name;  
  107. }
  108. public function getName(){  
  109. return  $this->_name;  
  110. }
  111. public function setDay($day){  
  112. $this->_day = $day;  
  113. }
  114. public function getDay(){  
  115. return  $this->_day ;  
  116. }
  117. public function setReason($reason ){  
  118. $this->_reason = $reason;  
  119. }
  120. public function getReason( ){  
  121. return  $this->_reason;  
  122. }
  123. }
  124. class client{  
  125. /** 
  126.      *流程1:leader-> manager ->generalManager 
  127.      * 
  128.      */  
  129. static function main(){  
  130. $leader = new ConcreteHandlerLeader('$leader');  
  131. $manager = new ConcreteHandlerManager('$manager');  
  132. $generalManager = new ConcreteHandlerGeneralManager('$generalManager');  
  133. //请求实例  
  134. $request = new Request('guisu',4,'休息' );  
  135. $leader->setSuccessor($manager);  
  136. $manager->setSuccessor($generalManager);  
  137. $result =  $leader->handleRequest($request);  
  138. }
  139. /** 
  140.      * 流程2 : 
  141.      * leader ->generalManager 
  142.      */  
  143. static function main2(){  
  144. //签字列表  
  145. $leader = new ConcreteHandlerLeader('$leader');  
  146. $manager = new ConcreteHandlerManager('$manager');  
  147. $generalManager = new ConcreteHandlerGeneralManager('$generalManager');  
  148. //请求实例  
  149. $request = new Request('guisu',3,'休息' );  
  150. $leader->setSuccessor($generalManager);  
  151. $result = $leader->handleRequest($request);  
  152. }
  153. /** 
  154.      * 流程3 :如果leader不在,那么完全可以写这样的代码 
  155.      * manager ->generalManager 
  156.      */  
  157. static function main3(){  
  158. //签字列表  
  159. $leader = new ConcreteHandlerLeader('$leader');  
  160. $manager = new ConcreteHandlerManager('$manager');  
  161. $generalManager = new ConcreteHandlerGeneralManager('$generalManager');  
  162. //请求实例  
  163. $request = new Request('guisu',0.1,'休息' );  
  164. $leader->setSuccessor($manager);  
  165. $manager->setSuccessor($generalManager);  
  166. $result = $manager->handleRequest($request);  
  167. }
  168. }
  169. client::main3();

对于怎么维护职责的链子,《设计模式》仅仅说自己去实现,可以使用list或者map的形式。

我们吧把职责链模式应用到面向过程编程,而不是对象。例如:

  1. 个税起征点3500元
  2. 级数   全月应纳税所得额            税率(%)
  3. 1    不超过1500元的                3
  4. 2    超过1500元至4500元的部分      10
  5. 3    超过4500元至9000元的部分      20
  6. 4    超过9000元至35000元的部分     25
  7. 5    超过35000元至55000元的部分    30
  8. 6    超过55000元至80000元的部分    35
  9. 7    超过80000元的部分              45

我们可以不必使用那么多的if和elseif语句判断。我们只要配置$taxs数组就可以了,而不用修改程序。

  1. <?php
  2. /** 
  3.  * 个税起征点3500元 
  4. 级数   全月应纳税所得额            税率(%) 
  5.    1    不超过1500元的                3 
  6.    2    超过1500元至4500元的部分      10 
  7.    3    超过4500元至9000元的部分      20 
  8.    4    超过9000元至35000元的部分     25 
  9.    5    超过35000元至55000元的部分    30 
  10.    6    超过55000元至80000元的部分    35 
  11.    7    超过80000元的部分             45 
  12. */  
  13. /** 
  14.  * 这个例子还没有扣除社保公积金等 
  15.  */  
  16. //收入  
  17. $income = 84000;  
  18. //税率  
  19. $taxs[1] = array(1500, 0.03);  
  20. $taxs[2] = array(4500, 0.1);  
  21. $taxs[3] = array(9000, 0.2);  
  22. $taxs[4] = array(35000, 0.25);  
  23. $taxs[5] = array(55000, 0.30);  
  24. $taxs[6] = array(80000, 0.35);  
  25. $taxs[7] = array(1000000000, 0.45);  
  26. /** 
  27.  * 计算税率 
  28.  * 
  29.  * @param int $income 
  30.  * @return int 
  31.  */  
  32. function compTax($income){  
  33. global $taxs;  
  34. //个税起点  
  35. $taxStart  = 3500;  
  36. $incomeTax = $income > $taxStart ?($income - $taxStart) : 0;  
  37. $flag = false;  
  38. foreach ($taxs as $values) {  
  39. if ($incomeTax < $values[0]  ) {  
  40. $compTax = $incomeTax * $values[1];  
  41. break;  
  42. }else{  
  43. continue;  
  44. }
  45. }
  46. return $compTax;  
  47. }
  48. echo compTax($income);  
  49. echo '-------------------<br/>';  
如果判断的条件很多,也就是数组$taxs很庞大。那么我们可以使用折半查找的方式:

  1. <?php
  2. /** 
  3.  * 个税起征点3500元 
  4. 级数   全月应纳税所得额            税率(%) 
  5.    1    不超过1500元的                3 
  6.    2    超过1500元至4500元的部分      10 
  7.    3    超过4500元至9000元的部分      20 
  8.    4    超过9000元至35000元的部分     25 
  9.    5    超过35000元至55000元的部分    30 
  10.    6    超过55000元至80000元的部分    35 
  11.    7    超过80000元的部分             45 
  12. */  
  13. /** 
  14.  * 这个例子还没有扣除社保公积金等 
  15.  */  
  16. //收入  
  17. $income = 84000;  
  18. //税率  
  19. $taxs[1] = array(1500, 0.03);  
  20. $taxs[2] = array(4500, 0.1);  
  21. $taxs[3] = array(9000, 0.2);  
  22. $taxs[4] = array(35000, 0.25);  
  23. $taxs[5] = array(55000, 0.30);  
  24. $taxs[6] = array(80000, 0.35);  
  25. $taxs[7] = array(1000000000, 0.45);  
  26. /** 
  27.  * 优化计算税率:使用折半查找法,有效缩短时间复杂度 
  28.  */  
  29. /** 
  30.  * 优化计算税率:折半查找法 
  31.  * 
  32.  * @param int $income 
  33.  * @return int 
  34.  */  
  35. function optimizeCompTax($income){  
  36. //个税起点  
  37. global $taxs;  
  38. $taxStart  = 3500;  
  39. $incomeTax = $income > $taxStart ?($income - $taxStart) : 0;  
  40. $key = bSearch($taxs, $incomeTax, 1);  
  41. return $incomeTax * $taxs[$key][1];  
  42. }
  43. /** 
  44.  *  
  45.  * 折半查找法 
  46.  * @param unknown_type $taxs 
  47.  * @param unknown_type $incomeTax 
  48.  * @return unknown 
  49.  */  
  50. function bSearch($taxs, $incomeTax, $start = 0){  
  51. $incomeTax = intval($incomeTax);  
  52. ksort($taxs);  
  53. foreach ($taxs as $key => $values) {  
  54. $low = $key;  
  55. break;  
  56. }
  57. if ($incomeTax <=0 ) {  
  58. return $low;  
  59. }
  60. $high = count($taxs) + $low -1;  
  61. while  ( $low < $high){  
  62. $mid = intval(($low + $high)/2) ;  
  63. if ( $incomeTax < $taxs[$mid][0] ) {//后半区找  
  64. $high = $mid;  
  65. else { //前半区找  
  66. $low = $mid ;  
  67. }
  68. /** 
  69.          * 由于这个不是完全折半查找 
  70.          * 只有两个元素的时候,需要判断 
  71.          */  
  72. if (($high - $low) ==1) {  
  73. if ( $incomeTax > $taxs[$low][0] ) {  
  74. $key = $high;  
  75. else{  
  76. $key = $low;  
  77. }
  78. break;  
  79. }
  80. }
  81. return $key;  
  82. }
  83. echo optimizeCompTax($income);  

10.与其他相关模式

职责链常与Composite组合模式一起使用。这种情况下,一个构件的父构件可作为它的后继

11.总结

在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。

职责链模式的主要优点在于可以降低系统的耦合度,简化对象的相互连接,同时增强给对象指派职责的灵活性,增加新的请求处理类也很方便;其主要缺点在于不能保证请求一定被接收,且对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。

相关文章:

Ubuntu使用QCustomPlot简介

参考网址 https://blog.csdn.net/zyc_csdn/article/details/78840376 显示实时数据 https://blog.csdn.net/qq_28877125/article/details/102948574?ops_request_misc&request_id&biz_id102&utm_termQcustomPlot%E4%BD%BF%E7%94%A8%E5%AE%9E%E6%97%B6%E5%8A%A8%E6…

Python入门基础教程 Working with Python – Introductory Level

学会像计算机科学家一样用世界上最流行的编程语言之一思考 你会学到: 学习Python的基础知识&#xff0c;Python是当今最流行的编程语言之一 通过编写一个基于文本的冒险游戏来学习Python语言的语法 了解面向对象编程和过程编程的区别 学会像计算机科学家一样思考:做决定、循环…

MyBatis复习笔记5:MyBatis代码生成器

前言&#xff1a;做过几个项目之后深感代码生成器的便捷&#xff0c;有了它我们可以少写许多重复的、基础的代码&#xff0c;如基本的增删改查的代码&#xff0c;我们可以交给代码生成器生成&#xff0c;而我们只需要专注于业务逻辑上的代码即可。 MyBatis Generator MyBatis官…

QT报错“qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method”

出现错误找这里&#xff1a;https://blog.csdn.net/u010168781/article/details/85632637

数据科学Python训练营课程:从初级到高级 Python for Data Science Bootcamp Course:Beginner to Advanced

通过代码实现、示例等&#xff0c;掌握您需要了解的关于Python、Pandas和Numpy的一切&#xff01; 你会学到什么 通过代码实现、示例等&#xff0c;掌握您需要了解的关于Python、Pandas和Numpy的一切&#xff01; 学习高级Python模块和复杂功能&#xff0c;如Python装饰器、生…

MyBatis复习笔记6:MyBatis缓存机制

MyBatis缓存机制 MyBatis 包含一个非常强大的查询缓存特性&#xff0c;它可以非常方便地配置和定制。缓存可以极大的提升查询效率。MyBatis系统中默认定义了两级缓存。一级缓存和二级缓存。 默认情况下&#xff0c;只有一级缓存&#xff08;SqlSession级别的缓存&#xff0c;也…

JAVA语法基础 3

一.实战演练 1.编写Java程序&#xff0c;声明2个int型变量&#xff0c;运用3元远算符判断两个变量是否相等&#xff0c;若不相等&#xff0c;求出两个数中较大的。 public class 练习题 { public static void main(String[] args) { int a1&#xff1b; int b2&#xff1b; Sys…

堆排序示例-java

package Heapsort; public class TestMain { /** * 调整堆 * param array 数组 * param i 调整的元素i * param length 堆元素个数 */ public static void adaptationArray(int[] array,int i, int length) { // 当前元素 int cur i; while(2*cur2<length) { int curValue …

创建新的ros工作空间

链接:https://www.cnblogs.com/ailitao/p/11047312.html

Blender左轮手枪制作教程

Artstation – Revolver Tutorial – Industry Ready Weapon & Attachment Creation for Video Games 持续时间19h 包含项目文件 1280X720 MP4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 大小解压后&#xff1a;16.6G 标题:艺术站-…

设计模式学习1:设计模式简述和设计模式原则

设计模式简述 什么是设计模式&#xff1f; 软件工程中&#xff0c;设计模式&#xff08;design pattern&#xff09;是对软件设计中普遍存在&#xff08;反复出现&#xff09;的各种问题&#xff0c;所提出的解决方案。 设计模式的目的&#xff1a; 代码高可用&#xff08;相…

mysql 常用sql与命令

1. 如何禁用和启用mysql外键约束 SET foreign_key_checks 0; 禁用外键SOURCE dump_file_name; 进行SQL查询 SET foreign_key_checks 1; 恢复外键 2. 把字段改为自动增长 SET foreign_key_checks 0; ALTER TABLE zz_news MODIFY COLUMN id BIGINT(20) NOT NULL AUTO…

需要恢复中断状态的一个场景

没有恢复中断状态时&#xff0c;在Step1执行期间发生中断&#xff0c;Step2操作还会继续&#xff0c;这就存在让数据出现不一致的风险&#xff1a; import java.util.concurrent.TimeUnit;import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*2015-4-9*/ public class …

新建ROS工作工作空间

空间解释&#xff1a; src:代码空间&#xff08;放置功能包&#xff1a;代码、配置文件、.launch文件&#xff09; build:编译空间&#xff08;编译文件&#xff1a;编译过程中产生的&#xff0c;不必去关心的&#xff09; devel:开发空间&#xff08;放置编译生成的可执行文件…

用Rhino V7建造机甲学习教程 Building a Mecha using Rhino V7

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:45节课(16h 55m) |大小解压后:10.8 GB 一级和二级初级和中级 你会学到: 通过一个手把手的项目学…

Nginx学习2:Nginx的安装配置和常用命令

Nginx的安装、常用命令和配置文件 在Linux系统安装Nginx 我们使用虚拟机来完成在Linux系统安装Nginx的步骤&#xff0c;在这里我选择的是CentOS7的Linux系统&#xff0c; 1、到官网下载Nginx 官网地址&#xff1a;http://nginx.org/en/download.html 我们选择稳定版的直接下…

鼠标悬浮指针变手

cursor:pointer; //鼠标悬浮样式转载于:https://www.cnblogs.com/GerryOfZhong/p/5219365.html

linux设备驱动第五篇:驱动中的并发与竟态

目录[-] 综述信号量与互斥锁Completions 机制自旋锁其他的一些选择不加锁算法原子变量与位操作seqlock&#xff08;顺序锁&#xff09;读取-拷贝-更新&#xff08;RCU&#xff09;小结综述 在上一篇介绍了linux驱动的调试方法&#xff0c;这一篇介绍一下在驱动编程中会遇到的并…

Ubuntu16.04运行.run文件

QT配置ROS环境,运行.run文件—参考链接: https://blog.csdn.net/have_fun_/article/details/88242536

终极AutoCAD大师班:成为AutoCAD专家

Ultimate AutoCAD Masterclass: Become an Expert in AutoCAD 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小:6.39 GB |时长:9h 58m 使用AutoCAD学习…

《深入理解Java虚拟机》(第二版)学习1:JVM的内存划分

运行时数据区 先来一张图描述一下 JVM 的内存划分 PS&#xff1a;自己画的&#xff0c;丑是难免丑了点… 程序计数器&#xff08;Program Counter Register&#xff09; 程序计数器&#xff08;Program Counter Register&#xff09;是一块较小的内存空间&#xff0c;它可以…

下一个亿万市场:企业级SaaS服务谁能独领风骚

注&#xff1a;SaaS是Software-as-a-Service(软件即服务)的简称&#xff0c;一种完全创新的软件应用模式&#xff0c;简单来说SaaS即为提供商基于互联网为企业提供软件服务。 ​对中小型企业来说&#xff1a;SaaS是采用先进技术&#xff0c;它消除了企业购买、构建和维护基础设…

inline-block在ie6中的经典bug

众所周知&#xff0c;给元素设置 inline-block &#xff0c;可以让ie下的元素出发layout:1。 但是&#xff0c;当给元素设置 inline-block 后&#xff0c;在另外一个class 样式&#xff08;非设置inline-block的class样式&#xff09;重置为inline或者block。对于ie6下&#xf…

各系统QT安装ROS后不显示src问题

刚创建的文件显示如下&#xff1a; 接下来修改这里&#xff1a; 将对勾去掉 之后就可以正常显示&#xff0c;可以添加自己的工作空间以及功能包了

使用脚本完成AutoCAD自动化任务课程

The complete AutoCAD Automation tasks course Using Script MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:42节课(4h 25m) |大小:3.35 GB 含课…

学生管理系统(C语言版)

学生管理系统 这个是大一学习C语言的时候做的一个小项目&#xff0c;代码部分基本都是自己一人完成&#xff0c;没用到什么高大上的技术&#xff0c;在图形化方面用了EasyX&#xff08;一个C的图形库&#xff09;&#xff0c;其他都是C语言的基础内容。 项目介绍 项目总体功…

jsp,图片显示

问题&#xff1a;jsp中显示项目中image文件夹中的图片 1&#xff0c;项目中image文件夹中有对应的图片 2&#xff0c;<img ,src"/项目名/image/图片名.jpg">&#xff0c;用其他变量获取这个路径也可以&#xff0c;但本质还是这个路径 3,对于jsp和HTML等文件的修…

Java基础系列——IO流

2019独角兽企业重金招聘Python工程师标准>>> ---恢复内容开始--- Java对数据的操作都是通过流的方式&#xff0c;数据的输入和输出是相对内存来说的&#xff0c;将外设的数据读到内存&#xff1a;输入流&#xff1b;将内存的数据写到外设&#xff1a;输出流。 流按…

Visual Studio Code / Roboware Studio调整字体大小,跳转等操作

调大字体:Ctrl 调小字体:Ctrl _- 跳转:F12 跳转返回:Ctrl Alt _- 打开内部终端:Ctrl ~

C4D和Redshift:2D矢量到三维渲染 Cinema 4D and Redshift: 2D vector to 3D render

C4D和Redshift:2D矢量到三维渲染 时长:1h 4m |视频:. MP4 1280720&#xff0c;30 fps(r) |音频:AAC&#xff0c;48000 Hz&#xff0c;2ch |大小解压后:633 MB 含课程文件 语言&#xff1a;英语中英文字幕(机译) 本课程涵盖了诸如将矢量转换为3d场景的主题。您将了解哪些数据可以…