王者荣耀中有一个观战系统。在观战系统中,玩家可以观看大神如何在战场上操作,从而学习大神出装、团战技巧等,同时也可以看好友如何战斗,以及回放自己的经典之战。观战系统的存在,可以让玩家们近距离观看大神或好友如何操作,针对练习更便捷。本地回放功能,完美保留精彩瞬间,战后回味别有一番趣味。
桥接模式理解: 高度概括:将抽象部分与它的实现部分分离,使他们都可以独立的变化. 抽象类或接口中可以定义若干个抽象方法,习惯上将抽象方法称作操作。抽象类或接口使程序的设计者忽略操作的细节,即不必考虑这些操作是如何实现的,当用户程序面向抽象类或接口时,就不会依赖具体的实现,使系统有很好的扩展性。但是,抽象类中的抽象方法总归是需要子类去实现的,在大多数情况下,抽象类的子类完全可以胜任这样的工作,但是,在某些情况下之,子类可能会遇到一些难以处理的问题,比如,不能因为有一个玩家想要观战不同的比赛,就要出现一个专门为该玩家制作比赛回放的子类。针对上述问题,我们称在Battle类和WatchWar类之间的关系是桥接关系,也就是说,Battle类的子类仅仅在Battle和WatchWar之间起到一个“桥接”的作用。 桥接模式是关于怎样将抽象部分与它的实现部分分离,使他们都可以独立的变化的成熟模式。
桥接模式结构中的四种角色: ①抽象(Abstraction):是一个抽象类,该类含有Implementor声明的变量,即维护一个Implementor类型对象; ②实现者(Implementor):实现者决策是一个接口(抽象类),该接口(抽象类)中的方法不一定与类中的方法一致。Implementor接口(抽象类)负责定义基本操作 而Abstraction类负责定义基于这些基本操作的较高层次的操作; ③细化抽象(Refined Abstraction):细化抽象是抽象角色的一个子类,该子类在重写(覆盖)抽象角色中的抽象方法时,在给出一些必要操作后,将委托所维护Implemento类型对象调用相应的方法; ④具体实现者(Concrete Impletementor):具体实现者是实现(扩展)Implementor接口(抽象类)的类。
桥接模式的UML类图:
桥接模式的优缺点: 优点: ①分离抽象接口及其实现部分,使得抽象和实现可以沿着各自的维度来变化; ②桥接模式有时类似于多继承方案。但是多继承方案违背了类的单一职责原则,复用性比较差,而且多继承结构中累的个数非常庞大,桥接模式是比多继承方案更好的解决办法; ③桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原系统; ④实现细节对客户透明,可以对用户隐藏实现细节; ⑤满足开-闭原则,抽象和实现者处于同层次,使系统可独立地扩展这两个层次。增加新的具体现者,不需要修改细化抽象,反之增加新的细化抽象也不需要修改具体实现; 缺点: ①桥接模式的引入会增加系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程; ②桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
桥接模式的适用情景: ①不想让抽象和某些重要的实现代码是固定的绑定关系,这部分实现可运行时动态决定; ②抽象和实现者都可以以继承的方式独立地扩充而互不影响,程序在运行期间可能需要动态的将一个抽象的子类的实例与一个实现者的子类的实例进行组合; ③希望对实现者层次代码的修改对抽象层不产生影响,即抽象层的代码不必重新编译,反之亦然。
此模式实例下的UML类图
eclipse结构图
主函数【应用(Application)】 Applicayion.java
package angle_bridgePattern;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Application extends JFrame{
JButton seeWar;
WatchWar watchWar;
Battle battle;
Application(WatchWar war,Battle battle){
watchWar=war;
this.battle=battle;
add(watchWar,BorderLayout.CENTER);
seeWar=new JButton("观战");
add(seeWar,BorderLayout.SOUTH);
seeWar.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
watchWar.makeWarContants();
}});
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public static void main(String args[]) {
Battle battle=new FriendsBattle();
WatchWar war=new FriendsWatchingWar(battle);
Application application1=new Application(war,battle);
application1.setBounds(10,10,200,300);
battle=new GreatGodBattle();
war=new GreatGodWatchingWar(battle);
Application application2=new Application(war,battle);
application2.setBounds(220,10,200,300);
}
}
抽象 WatchWar.java
package angle_bridgePattern;
import javax.swing.*;
import java.awt.*;
public abstract class WatchWar extends JPanel{
Battle battleMaker;
public abstract void makeWarContants () ;
}
实现者 Battle.java
package angle_bridgePattern;
import java.util.ArrayList;
public interface Battle{
public ArrayList<String> makeBattle();
}
细化抽象 FriendsWatchingWar.java
package angle_bridgePattern;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class FriendsWatchingWar extends WatchWar implements Runnable{
JLabel showWar;
Thread thread;
ArrayList<String> content;
FriendsWatchingWar(Battle battle){
battleMaker=battle;
setLayout(new BorderLayout());
showWar=new JLabel("好友观战");
showWar.setFont(new Font("",Font.BOLD,39));
add(showWar,BorderLayout.CENTER);
thread=new Thread(this);
}
public void makeWarContants (){
content=battleMaker.makeBattle();
if(!thread.isAlive()){
thread=new Thread(this);
thread.start();
}
}
public void run(){
for(int i=0;i<content.size();i++){
showWar.setText(content.get(i));
try{ Thread.sleep(1500);
}
catch(InterruptedException exp){}
}
}
}
GreatGodWatchingWar.java
package angle_bridgePattern;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class GreatGodWatchingWar extends WatchWar implements Runnable{
JLabel showWar;
Thread thread;
ArrayList<String> content;
GreatGodWatchingWar(Battle battle){
battleMaker=battle;
setLayout(new BorderLayout());
showWar=new JLabel("大神观战");
showWar.setFont(new Font("",Font.BOLD,39));
add(showWar,BorderLayout.CENTER);
thread=new Thread(this);
}
public void makeWarContants (){
content=battleMaker.makeBattle();
if(!thread.isAlive()){
thread=new Thread(this);
thread.start();
}
}
public void run(){
for(int i=0;i<content.size();i++){
showWar.setText(content.get(i));
try{ Thread.sleep(1500);
}
catch(InterruptedException exp){}
}
}
}
具体实现者 FriendsBattle.java
package angle_bridgePattern;
import angle_bridgePattern.Battle;
import java.util.ArrayList;
public class FriendsBattle implements Battle{
ArrayList<String> content;
FriendsBattle(){
content=new ArrayList<String>();
}
public ArrayList<String> makeBattle(){
content.clear();
content.add("好友【峡谷一级演员】选择嬴政出战");
content.add("好友【峡谷一级演员】使用嬴政击杀敌方英雄获得一血");
content.add("好友【峡谷一级演员】使用嬴政“无人能挡”");
content.add("好友【峡谷一级演员】向队友发出“集合,保护我方水晶”信号");
content.add("晋级对局结束!好友【峡谷一级演员】晋级失败!");
return content;
}
}
GreatGodBattle.java
package angle_bridgePattern;
import angle_bridgePattern.Battle;
import java.util.ArrayList;
public class GreatGodBattle implements Battle{
ArrayList<String> content;
GreatGodBattle(){
content=new ArrayList<String>();
}
public ArrayList<String> makeBattle(){
content.clear();
content.add("大神玩家【小心边路反杀】选择橘右京出战");
content.add("大神玩家【小心边路反杀】使用橘右京击杀敌方英雄获得一血");
content.add("大神玩家【小心边路反杀】使用橘右京“大杀特杀”");
content.add("大神玩家【小心边路反杀】向队友发出“集合,攻击敌方水晶”信号");
content.add("对局结束!大神玩家获得胜利!");
return content;
}
}
运行结果截图
更多设计模式在王者荣耀中的应用请点击我的→设计模式在王者荣耀中的应用专栏。
感谢阅读