首页 文章 精选 留言 我的

精选列表

搜索[java],共10000篇文章
优秀的个人博客,低调大师

JAVA中的设计模式四(装饰模式)

-------装饰模式 装饰模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。 -------1.介绍 意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。 主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。 何时使用:在不想增加很多子类的情况下扩展类。 如何解决:将具体功能职责划分,同时继承装饰者模式。 关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。 应用实例: 1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。 优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。 缺点:多层装饰比较复杂。 使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。 注意事项:可代替继承。 -------2.实例 2.1把一个形状装饰上不同的颜色,同时又不改变形状类 2.1.1.我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后我们创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。 2.1.2.RedShapeDecorator 是实现了 ShapeDecorator 的实体类。 2.1.3.test,我们的演示类使用 RedShapeDecorator 来装饰 Shape 对象。 1 package decorate; 2 3 /** 4 * @author Administrator 5 * 形状接口 6 */ 7 public interface Shape { 8 void draw(); 9 } 10 11 12 13 package decorate; 14 15 /** 16 * @author Administrator 17 *长方形 18 */ 19 public class Rectangle implements Shape { 20 21 @Override 22 public void draw() { 23 // TODO Auto-generated method stub 24 System.out.println("形状:长方形"); 25 } 26 27 28 } 29 30 31 32 33 34 package decorate; 35 36 /** 37 * @author Administrator 38 *圆形 39 */ 40 public class Circle implements Shape { 41 42 @Override 43 public void draw() { 44 // TODO Auto-generated method stub 45 System.out.println("形状:圆形"); 46 } 47 48 49 } 50 51 52 53 54 package decorate; 55 56 /** 57 * @author Administrator 58 * 装饰对象 59 */ 60 public abstract class ShapeDecorator implements Shape {//装饰器 61 protected Shape decoratedShape; 62 @Override 63 public void draw() { 64 // TODO Auto-generated method stub 65 decoratedShape.draw(); 66 } 67 public ShapeDecorator(Shape decoratedShape) { 68 this.decoratedShape = decoratedShape; 69 } 70 71 72 } 1 package decorate; 2 3 /** 4 * @author Administrator 5 * 颜色 红色 6 */ 7 public class RedShapeDecorator extends ShapeDecorator { 8 9 public RedShapeDecorator(Shape decoratedShape) { 10 super(decoratedShape); 11 // TODO Auto-generated constructor stub 12 } 13 14 @Override 15 public void draw() { 16 // TODO Auto-generated method stub 17 decoratedShape.draw(); 18 setRedBorder(decoratedShape); 19 } 20 21 public void setRedBorder(Shape decoratedShape){ 22 System.out.println("颜色: Red"); 23 } 24 25 } 1 package decorate; 2 3 public class Test { 4 public static void main(String[] args) { 5 Shape shape=new Circle(); 6 Shape redCircle=new RedShapeDecorator(new Circle()); 7 shape.draw(); 8 System.out.println(); 9 redCircle.draw(); 10 } 11 } 输出结果: 形状:圆形 形状:圆形 颜色: Red 2.2.装饰模式为已有类动态附加额外的功能就像LOL英雄升级一样。每次英雄升级都会附加一个额外技能点学习技能。 1 package lol; 2 3 /** 4 * @author GH 5 * 英雄接口 6 */ 7 public interface Hero { 8 void study(); 9 } 10 11 12 13 package lol; 14 15 /** 16 * @author GH 17 * 具体的英雄 蛮王 18 */ 19 public class BarbarianKing implements Hero { 20 private String name; 21 @Override 22 public void study() { 23 // TODO Auto-generated method stub 24 System.out.println("英雄:"+name); 25 } 26 public BarbarianKing(String name) { 27 super(); 28 this.name = name; 29 } 30 31 } 32 33 34 35 package lol; 36 37 /** 38 * @author Administrator 39 * 技能装饰器 40 */ 41 public abstract class Skills implements Hero{ 42 protected Hero heroSkill; 43 44 public Skills(Hero heroSkill) { 45 this.heroSkill = heroSkill; 46 } 47 @Override 48 public void study() { 49 // TODO Auto-generated method stub 50 heroSkill.study(); 51 } 52 } 53 54 55 56 package lol; 57 58 /** 59 * @author Administrator 60 *具体技能Q 61 */ 62 public class KillQ extends Skills { 63 64 public KillQ(Hero heroSkill) { 65 super(heroSkill); 66 // TODO Auto-generated constructor stub 67 } 68 69 @Override 70 public void study() { 71 // TODO Auto-generated method stub 72 heroSkill.study(); 73 setkill(heroSkill); 74 } 75 public void setkill(Hero hero){ 76 System.out.println("习得技能:Q"); 77 } 78 79 } 80 81 82 83 package lol; 84 85 /** 86 * @author Administrator 87 *具体技能W 88 */ 89 public class KillW extends Skills { 90 91 public KillW(Hero heroSkill) { 92 super(heroSkill); 93 // TODO Auto-generated constructor stub 94 } 95 96 @Override 97 public void study() { 98 // TODO Auto-generated method stub 99 heroSkill.study(); 100 setkill(heroSkill); 101 } 102 public void setkill(Hero hero){ 103 System.out.println("习得技能:W"); 104 } 105 106 } 107 108 109 package lol; 110 111 public class Test { 112 113 public static void main(String[] args) { 114 // TODO Auto-generated method stub 115 Hero hero=new BarbarianKing("蛮王"); 116 hero.study(); 117 System.out.println(); 118 KillQ q=new KillQ(hero); 119 q.study(); 120 121 System.out.println(); 122 KillQ q2=new KillQ(q); 123 q2.study(); 124 125 System.out.println(); 126 KillW w=new KillW(q2); 127 w.study(); 128 } 129 130 } 输出结果: 英雄:蛮王 英雄:蛮王 习得技能:Q 英雄:蛮王 习得技能:Q 习得技能:Q 英雄:蛮王 习得技能:Q 习得技能:Q 习得技能:W -------3.总结: 装饰模式是为已有功能动态的添加更多功能的一种方式。当系统需要新功能的时候,通过新加代码来装饰原有类的核心职责,而这些新加的东西仅仅是为了满足一些只在特殊情况下才会执行的特殊行为。装饰模式的有点其实就是:把类中装饰功能从类中搬除出去,在简化原有类的基础上有效的把类的核心职责和装饰功能区分开来。欢迎大家一起说出自己的想法。

优秀的个人博客,低调大师

Java并发编程的艺术(十三)——锁优化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34173549/article/details/80289271 自旋锁 背景:互斥同步对性能最大的影响是阻塞,挂起和恢复线程都需要转入内核态中完成;并且通常情况下,共享数据的锁定状态只持续很短的一段时间,为了这很短的一段时间进行上下文切换并不值得。 原理:当一条线程需要请求一把已经被占用的锁时,并不会进入阻塞状态,而是继续持有CPU执行权等待一段时间,该过程称为『自旋』。 优点:由于自旋等待锁的过程线程并不会引起上下文切换,因此比较高效; 缺点:自旋等待过程线程一直占用CPU执行权但不处理任何任务,因此若该过程过长,那就会造成CPU资源的浪费。 自适应自旋:自适应自旋可以根据以往自旋等待时间的经验,计算出一个较为合理的本次自旋等待时间。 锁清除 编译器会清除一些使用了同步,但同步块中没有涉及共享数据的锁,从而减少多余的同步。 锁粗化 若有一系列操作,反复地对同一把锁进行上锁和解锁操作,编译器会扩大这部分代码的同步块的边界,从而只使用一次上锁和解锁操作。 轻量级锁 本质:使用CAS取代互斥同步。 背景:『轻量级锁』是相对于『重量级锁』而言的,而重量级锁就是传统的锁。 轻量级锁与重量级锁的比较: 重量级锁是一种悲观锁,它认为总是有多条线程要竞争锁,所以它每次处理共享数据时,不管当前系统中是否真的有线程在竞争锁,它都会使用互斥同步来保证线程的安全; 而轻量级锁是一种乐观锁,它认为锁存在竞争的概率比较小,所以它不使用互斥同步,而是使用CAS操作来获得锁,这样能减少互斥同步所使用的『互斥量』带来的性能开销。 实现原理: 对象头称为『Mark Word』,虚拟机为了节约对象的存储空间,对象处于不同的状态下,Mark Word中存储的信息也所有不同。 Mark Word中有个标志位用来表示当前对象所处的状态。 当线程请求锁时,若该锁对象的Mark Word中标志位为01(未锁定状态),则在该线程的栈帧中创建一块名为『锁记录』的空间,然后将锁对象的Mark Word拷贝至该空间;最后通过CAS操作将锁对象的Mark Word指向该锁记录; 若CAS操作成功,则轻量级锁的上锁过程成功; 若CAS操作失败,再判断当前线程是否已经持有了该轻量级锁;若已经持有,则直接进入同步块;若尚未持有,则表示该锁已经被其他线程占用,此时轻量级锁就要膨胀成重量级锁。 前提:轻量级锁比重量级锁性能更高的前提是,在轻量级锁被占用的整个同步周期内,不存在其他线程的竞争。若在该过程中一旦有其他线程竞争,那么就会膨胀成重量级锁,从而除了使用互斥量以外,还额外发生了CAS操作,因此更慢! 偏向锁 作用:偏向锁是为了消除无竞争情况下的同步原语,进一步提升程序性能。 与轻量级锁的区别:轻量级锁是在无竞争的情况下使用CAS操作来代替互斥量的使用,从而实现同步;而偏向锁是在无竞争的情况下完全取消同步。 与轻量级锁的相同点:它们都是乐观锁,都认为同步期间不会有其他线程竞争锁。 原理:当线程请求到锁对象后,将锁对象的状态标志位改为01,即偏向模式。然后使用CAS操作将线程的ID记录在锁对象的Mark Word中。以后该线程可以直接进入同步块,连CAS操作都不需要。但是,一旦有第二条线程需要竞争锁,那么偏向模式立即结束,进入轻量级锁的状态。 优点:偏向锁可以提高有同步但没有竞争的程序性能。但是如果锁对象时常被多条线程竞争,那偏向锁就是多余的。 偏向锁可以通过虚拟机的参数来控制它是否开启。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册