设计模式之禅之包装模式群大PK【装饰模式VS适配器模式VS门面模式VS代理模式VS桥梁模式】
包装模式群大PK
写在前面
- 这么多的设计模式,大家有没有发觉在很多的模式中有角色是不干活的,他们只充当着黔首作用,你有问题,找我,但是我不处理,我让其他人处理,最典型的就是代理模式了,代理角色接收请求然后传递到被代理角色处理。门面模式也是一样,门面模式的任务就是把请求转发到子系统,类似这种结构的模式还有很多,我们先给这种结构类型的模式起一个名称,叫做包装模式。
包装模式:是一种模式,而不是一个模式,包括
- 装饰模式
- 适配器模式
- 门面模式
- 代理模式
- 桥梁模式
五种模式的区别
代理模式
从明星的经纪人说起
类图
代码实现
Agent
#
package com.peng.baozhuang1;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Agent implements IStar {
private IStar star;// 定义谁的经纪人
public Agent(IStar star) {
super();
this.star = star;
}
@Override
public void sign() {
// 经纪人是不会签名的,得靠具体的明星来签名
System.out.println("我是经纪人:下列签名由明星来签!");
star.sign();
}
}
Idolater
#
package com.peng.baozhuang1;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Idolater {
public static void main(String[] args) {
// 崇拜的明星是谁
IStar star = new Single();
// 找明星的经纪人
IStar agent = new Agent(star);
// 崇拜者要明星的签名
System.out.println("我是你的崇拜者,我想要你的签名");
agent.sign();
}
}
IStar
#
package com.peng.baozhuang1;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public interface IStar {
// 明星都会签名
public void sign();
}
Single
#
package com.peng.baozhuang1;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Single implements IStar {
@Override
public void sign() {
System.out.println("明星签名:我是KungFu~Peng");
}
}
执行结果
#
我是你的崇拜者,我想要你的签名
我是经纪人:下列签名由明星来签!
明星签名:我是KungFu~Peng
装饰模式
粉饰一个演员
类图
代码
Client
#
package com.peng.baozhuang2;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Client {
public static void main(String[] args) {
// 定义出明星
IStar star = new FreakStar();
// 粉饰自己
System.out.println("==========表演前=========");
HotAir ha = new HotAir(star);
ha.act();
System.out.println("===========表演后=========");
Deny dy = new Deny(star);
dy.act();
}
}
Decorator
#
package com.peng.baozhuang2;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public abstract class Decorator implements IStar {
// 粉饰的是谁
private IStar star;
public Decorator(IStar star) {
super();
this.star = star;
}
@Override
public void act() {
this.star.act();
}
}
Deny
#
package com.peng.baozhuang2;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Deny extends Decorator {
public Deny(IStar star) {
super(star);
}
public void act() {
super.act();
// 表演结束后的死不承认
System.out.println("表演后:百般抵赖,死不承认!");
}
}
FreakStar
#
package com.peng.baozhuang2;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class FreakStar implements IStar {
@Override
public void act() {
System.out.println("表演中:演技很拙劣~~");
}
}
HotAir
#
package com.peng.baozhuang2;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class HotAir extends Decorator {
public HotAir(IStar star) {
super(star);
}
public void act() {
System.out.println("表演前的夸夸其谈");
super.act();
}
}
IStar
#
package com.peng.baozhuang2;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public interface IStar {
// 演戏
public void act();
}
执行结果
#
==========表演前=========
表演前的夸夸其谈
表演中:演技很拙劣~~
===========表演后=========
表演中:演技很拙劣~~
表演后:百般抵赖,死不承认!
适配器模式
演员的替身
类图
代码
Director
#
package com.peng.baozhuang3;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Director {
public static void main(String[] args) {
System.out.println("=======演戏过程模拟========");
// 定义一个大明星
IStar star = new FilmStar();
star.act("前十分钟,明星本人出演~~");
// 中间5分钟提示来演
IActor actor = new UnknownActor();
IStar standin = new Standin(actor);
standin.act("中间五分钟,替身来演");
// 最后十分钟,明星来演
star.act("最后十分钟,明星本人来演");
}
}
FilmStar
#
package com.peng.baozhuang3;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class FilmStar implements IStar {
@Override
public void act(String context) {
System.out.println("明星演戏:" + context);
}
}
IActor
#
package com.peng.baozhuang3;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public interface IActor {
// 普通演员演戏
public void playact(String contet);
}
IStar
#
package com.peng.baozhuang3;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public interface IStar {
// 明星都要演戏
public void act(String context);
}
Standin
#
package com.peng.baozhuang3;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Standin implements IStar {
// 替身是谁
private IActor actor;
public Standin(IActor actor) {
super();
this.actor = actor;
}
@Override
public void act(String context) {
actor.playact(context);
}
}
UnknownActor
#
package com.peng.baozhuang3;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class UnknownActor implements IActor {
@Override
public void playact(String contet) {
// 普通演员演戏
System.out.println("普通演员演戏:" + contet);
}
}
执行结果
#
=======演戏过程模拟========
明星演戏:前十分钟,明星本人出演~~
普通演员演戏:中间五分钟,替身来演
明星演戏:最后十分钟,明星本人来演
桥梁模式
明星类型太多了:
- 电影明星
- 电视明星
- 歌星
- 体育明星
- 网络明星
- 。。。
明星可能身兼数职,即多元化发展
类图
代码
AbsAction
#
package com.peng.baozhuang4;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public abstract class AbsAction {
//每个活动都有描述
public abstract void desc();
}
AbsStar
#
package com.peng.baozhuang4;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public abstract class AbsStar {
// 一个明星参加那些活动
protected final AbsAction action;
// 通过构造函数传递参数
public AbsStar(AbsAction action) {
super();
this.action = action;
}
// 每个明星都有自己的工作
public void doJob() {
action.desc();
}
}
ActFilm
#
package com.peng.baozhuang4;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class ActFilm extends AbsAction {
@Override
public void desc() {
System.out.println("演出精彩绝伦的电影");
}
}
Client
#
package com.peng.baozhuang4;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Client {
public static void main(String[] args) {
// 声明一个电影明星
AbsStar zhangSan = new FilmStar();
// 声明一个歌星
AbsStar liSi = new Singer();
// 展示一下各个明星的主要工作
zhangSan.doJob();
liSi.doJob();
// 也有部分明星不务正业
liSi = new Singer(new ActFilm());
liSi.doJob();
}
}
FilmStar
#
package com.peng.baozhuang4;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class FilmStar extends AbsStar {
// 默认的电影明星的主要工作是拍电影
public FilmStar() {
super(new ActFilm());
}
// 也可以重新设置一个新的角色
public FilmStar(AbsAction action) {
super(action);
}
// 细化电影明星的职责
public void doJob() {
System.out.println("\n======影星的工作=========");
super.doJob();
}
}
Sing
#
package com.peng.baozhuang4;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Sing extends AbsAction {
@Override
public void desc() {
System.out.println("唱出优美的歌曲");
}
}
Singer
#
package com.peng.baozhuang4;
/**
* @author kungfu~peng
* @data 2018年1月6日
* @description
*/
public class Singer extends AbsStar {
// 默认的歌星的主要工作是拍唱歌
public Singer() {
super(new Sing());
}
// 也可以重新设置一个新的角色
public Singer(AbsAction action) {
super(action);
}
// 细化歌星的职责
public void doJob() {
System.out.println("\n======歌星的工作=========");
super.doJob();
}
}
执行结果
#
======影星的工作=========
演出精彩绝伦的电影
======歌星的工作=========
唱出优美的歌曲
======歌星的工作=========
演出精彩绝伦的电影
最佳实践
综述
5个包装模式是大家在系统设计中经常使用到的模式,它们具有相似的特征:
- 都是通过委托的方式对一个对象或一系列的对象进行包装
- 有了包装,设计的系统才更加的灵活,稳定,并且极具扩展性
- 从实现的角度来看,它们都是代理的具体表现形式
代理模式
- 主要用在不希望展示一个对象内部细节的场景之中,比如一个远程服务不需要把远程连接的所有细节都暴露给外部模块,通过一个代理类,可以很轻松的实现被代理类对象的封装。此外,代理模式还可以用在一个对象的访问需要限制的场景中,比如AOP
装饰模式
- 是一种特殊的代理模式,他倡导的是不改变接口的前提下为对象增强功能,或者动态添加额外职责,就扩展性而言,他比子类更加灵活
适配器模式
- 适配器模式的主要意图是接口转换,把一个对象的接口转换成希望的另外一个接口,这里的系统指的不仅仅是一个应用,也可以是某个环境,比如可以通过接口转换可以屏蔽外界的接口,以免受外界深入系统内部,从而提高系统的稳定性和可靠性
桥梁模式
- 桥梁模式是在抽象层产生耦合,解决的是自行扩展的问题,它可以使两个耦合关系的对象互不影响的扩展
门面模式
- 门面模式是一个粗粒度的封装,它提供一个方便访问子系统的接口,不具有任何的业务逻辑,仅仅是一个访问复杂的快速通道,没有它,子系统照样运行,有了它,只是更方便的运行而已
还没有评论,来说两句吧...