桥接模式coding

package com.learn.design.pattern.structural.bridge;/*** 在这里有两个方法* * * @author Leon.Sun**/
public interface Account {/*** 一个呢是打开我们的账号* 打开账号又分为打开哪个银行的账号呢* 例如leon有工商银行的账号* 还有中国农业银行的账号* 所以这里也是一个抽象* 那既然打开账号呢* 就要返回账号* openAccount这么一个方法* * * @return*/Account openAccount();/*** 还有是查看我们账户的类型* 是活期储蓄* 还是定期储蓄* 还有一个showAccountType* 看一下这个账号的类型* 就现在的场景而言* 我们有中国农业银行* 中国工商银行* 这是两个银行* 还有有活期账号* 还有定期账号* 这个呢是两个不同类型的账号* 他们交叉一下* 就会有四种组合* 那一旦说我们的银行不断的扩展* 账号类型也不断地扩展的话* 那么对于桥接模式* 就再适合不过了* 他们两个都可以随着自己的层级* 进行扩展* 随着我们coding的时候呢* 希望对这一块的理解呢* 会加深* 首先呢我们创建一个定期账号* 来实现这个接口* DepositAccount* * */void showAccountType();}
package com.learn.design.pattern.structural.bridge;/*** 他来实现Account* 实现两个方法* 这个账号是一个定期账号* 我们再创建一个活期账号的类* 新建一个类* SavingAccount* DepositAccount是定期存款* 如果提前取出来的话需要交罚金的* * * * @author Leon.Sun**/
public class DepositAccount implements Account {/*** 写一下这个类的实现* * */@Overridepublic Account openAccount() {/*** 首先输出* "打开定期账号"* * */System.out.println("打开定期账号");/*** 返回值直接new一个* 非常适合回来来看* 写完之后你们先体会* 回头来给大家讲* 因为我几年前在学模式的时候* 当时从上至下的来学习的时候* 理解的并不是很透彻* 但是一旦写完之后* 再回头来看* 一切都非常清晰明了* 我们边写也会边讲* 一起来体会* 我们再回头重点来讲* 那我们继续来coding* 那现在就得写我们的银行类* 创建一个类Bank* * */return new DepositAccount();}@Overridepublic void showAccountType() {/*** 这个是一个定期账号* * 直接到这里* 这是一个定期账号* 那这个时候F8通过* * */System.out.println("这是一个定期账号");}
}
package com.learn.design.pattern.structural.bridge;/*** 他也实现Account接口* 实现这两个方法* SavingAccount是随时可以取钱的那种* * * @author Leon.Sun**/
public class SavingAccount implements Account {/*** 打开这个账号需要返回这个账号* * */@Overridepublic Account openAccount() {/*** 所以我们输出一下打个标记* * */System.out.println("打开活期账号");//.../*** new一个SavingAccount* * */return new SavingAccount();}@Overridepublic void showAccountType() {/*** 直接输出"这是一个活期账号"* * */System.out.println("这是一个活期账号");}
}
package com.learn.design.pattern.structural.bridge;/*** 这个银行类很简单* 他要写成一个抽象类* 为什么呢* 因为现在我们要把Account* 引入到Bank里边* 然后通过这种组合的方式* 交给子类来实现他的行为* 而这个行为就是openAccount* 至少我要确定* 打开的是哪个银行的账号* 那首先呢既然要交给子类* * * @author Leon.Sun**/
public abstract class Bank {/*** protected* 声明一个account* 子类能够拿到Account* 然后我来写一下他的构造器* * */protected Account account;/*** 构造器我可以把account拿过来* 也可以通过set注入的方式* * 然后在父类上也打一个断点* * 所以就把这个account赋值给抽象类Bank* 里面组合的Account* F6单步* 可以看到这个时候已经有值了* * * @param account*/public Bank(Account account){/*** 然后赋值* 把这些断点去掉* 看一下结果* 那在使用桥接模式的时候* 有一个小坑* 这个小坑是什么呢* 例如我们现在打开中国工商银行账号* 然后直接显示了这是一个定期账号* 这个没有什么问题* 但是我们要注意* 我们委托之后* 到底有没有使用他呢* 我们看一下* * */this.account = account;}/*** 然后我们要写一个抽象方法* 那这个方法是什么呢* 正式Account接口的方法* 那一会就知道* 为什么我这个想抽象类里边* 还要写一个抽象方法* 而这个抽象方法* 和接口里面声明的* 抽象方法是一样的* 那这里面我也要强调一下* 声明成一样的方法名* 这个并不是强制的* 那我们声明成一样的方法名呢* 是为了你们更方便的理解* 因为Bank里面的具体的方法* 要委托给Account的openAccount* 这个方法* 所以就把它们声明成一样的方法名* 其实不叫一样的方法名也是OK的* 只不过这种委托关系* 在我们这个case里边* 逻辑比较简单* 并不会增强这个openAccount方法* 所以就直接委托给他* 他们两个的方法名是一样的* 里边的实现所表达的含义也是一样的* 然后这里边再说一下* 看到的Account类* 那在我们现在这个结构中* Account就是具体的实现* 因为我们要通过Account的接口实现* Bank就是抽象* 然后抽象类里面的某个行为* 委托给Account这个接口* 那前面我们也有说* 桥接模式是指抽象和实现分离* 那实现是什么呢* 实现正式Account的两个实现类* 那Account是有名词的含义* 那还有动词* 动词就是报账 查账* 我们可以认为Account是一个行为接口* 里面是两个动作* 一个是open* 一个是show* 打开账号* 还是查看账号类型呢* 这些都是动作* 那这里面还要再强调一次* 抽象和实现分离* 在桥接模式当中* 抽象是指抽象类* 因为还有各种扩展* 而具体的实现呢* 一般也都是行为* 这里也说了* 当然不排除特殊情况* 这里面的account也是动词* 那桥接模式当中的实现* 就是Account的两个接口实现* 而这个方法名字* 并不强制一模一样* 不过我们这里是强制委托* 如果方法要达到的目的是一模一样的* 所以就直接copy这个方法名了* 这里面还是比较灵活的* 并没有强制限制* 那我们现在来创建中国农业银行* ABCBank* * * @return*/abstract Account openAccount();
}
package com.learn.design.pattern.structural.bridge;/*** 他继承Bank* 这个抽象父类* * * @author Leon.Sun**/
public class ABCBank extends Bank {/*** 红线说没有构造器* 我们构造一个* 调用super* 调用父类的构造器* * * @param account*/public ABCBank(Account account) {super(account);}/*** 这里面实现就很简单了* 构造的时候传入的什么Account* 就返回什么Account* 而这个Account正式父类的Account* 所以这里面直接返回Account就可以了* * */@OverrideAccount openAccount() {/*** 直接输出* "打开中国农业银行账号"* 同时我们建立一个爱存不存账号* ICBCBank* * */System.out.println("打开中国农业银行账号");/*** 然后调用了ICBCBank* 很明显这个就是ICBC的银行* 所以他肯定知道这个是中国工商银行* 那具体是什么账号* 他把它再进行一个返回* 那这个返回之后* 就来到了DepositAccount* * 在这里我们有时候写业务逻辑的时候* 经常有忘记委托的这种情况* 隐瞒了一个点* 这个平时在使用桥接模式的时候* 一定不要忘记* 不要把具体的实现自己完成* 而是要委托给Account来实现* 否则创建相同名字的方法* 也就没有意义了* 因为只有通过具体的委托* 以后account里边的openAccount方法* 如果扩展的话* Bank这里边是不需要动的* 不要把这个实现移到openAccount里边* 这里一定要注意* 一定要把你具体的行为委托出去* 委托给谁呢* 正是委托给注入的Account* 那我们再run一下* 来看一下实际的结果* 刚刚那个小坑也是故意埋下的一个伏笔* 希望通过这坑* 一定要印象深刻* 我们再看一下结果* * */account.openAccount();return account;}
}
package com.learn.design.pattern.structural.bridge;/*** 继承Bank这个类* * @author Leon.Sun**/
public class ICBCBank extends Bank {/*** 然后构造器加上* * * @param account*/public ICBCBank(Account account) {/*** 进入这里* * F6* 现在来创建工商银行* 并且把这个账号拿过来了* 他呢又调用父类的构造器* * */super(account);}@OverrideAccount openAccount() {/*** 打开的是工商银行账号* 现在我们来看一下UML图* * 注意这里* 我们打开中国工商银行账号之后* 我们要把具体的行为委托给Account* * */System.out.println("打开中国工商银行账号");/*** 调用它的openAccount* 这样才是真正实现openAccount这个行为* 委托给account* 委托来执行* 所以ABCBank也是一样的* * */account.openAccount();/*** 直接return account* */return account;}
}
package com.learn.design.pattern.structural.bridge;/*** * @author Leon.Sun**/
public class Test {public static void main(String[] args) {/*** 我们创建一个银行* 爱存不存银行* ICBCBank* 这里面放一个DepositAccount* * 首先我们进入他的构造器来看一下* * */Bank icbcBank = new ICBCBank(new DepositAccount());/*** 然后从这里面拿一个账号* icbcBank.openAccount* 打开这个账号* * 这里打开了中国工商银行账号* * 同时打开这个银行之后* 我又打开了定期账号* 这是因为我们把定期账号* 注入到ICBC账号里边* 所以他打开账号的时候* 首先打开中国工商银行账号* 然后打开里面具体的的定期账号* * */Account icbcAccount = icbcBank.openAccount();/*** 然后调用它的showAccountType方法* * 这里是一个定期账号* * 最后show一下AccountType* 也就是这个* 现在这个使用才是非常标准的使用方式* 现在我们再结合前面的原则来说* 如果我们不把具体的实现委托给Account* 这个接口的话* 那我们对ABC Account的实现* 是非常可能不符合迪米特原则的* 那我们回来再看一下* */icbcAccount.showAccountType();/*** 后面直接加一个2* 那现在我们来run一下* 我们来看一下结果* ***/Bank icbcBank2 = new ICBCBank(new SavingAccount());/*** 这里打开一个中国工商银行账号* * */Account icbcAccount2 = icbcBank2.openAccount();/*** 这个是一个活期账号* * */icbcAccount2.showAccountType();/*** 这个时候我再创建一个ABCBank* 这里面就换一下了* SavingAccount* 这个时候即使我需要一个工商银行的SavingAccount* 也是很容易的* 我们直接copy一份出来* * * */Bank abcBank = new ABCBank(new SavingAccount());/*** 打开中国农业银行账号* * */Account abcAccount = abcBank.openAccount();/*** 这是一个活期账号* 那现在debug来跟一个* 非常简单* 我们直接run debug* * */abcAccount.showAccountType();}
}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部