5种包装模式
包装模式包括:代理模式、装饰模式、适配器模式、桥梁模式、门面模式。
相似的特征:都是通过委托的方式对一个对象或一系列对象施行包装。从实现的角度来看,它们都是代理的一种具体表现形式。
使用场景的区别:
- 代理模式:主要用在不希望展示一个对象内部细节的场景中。
- 装饰模式:倡导的是在不改变接口的前提下为对象增强功能,或者动态添加额外职责。
- 适配器模式:主要意图是接口转换,把一个对象的接口转换成系统希望的另外一个接口
- 桥梁模式:在抽象层产生耦合,它可以使两个有耦合关系的对象互不影响地扩展。(笔画图:笔和图分别处理)
- 门面模式:一个粗粒度的封装,不具有任何的业务逻辑,仅仅是一个访问复杂系统的快速通道。
(1)代理模式
追星族想找明星签字,需要经过经纪人。
public interface IStar {
public void sign();
}
//明星
import com.sfq.impl.IStar;
public class Singer implements IStar {
@Override
public void sign() {
System.out.println("签名:XXX");
}
}
//经纪人
import com.sfq.impl.IStar;
public class Agent implements IStar {
//定义是谁的经纪人
private IStar star;
public Agent(IStar star) {
this.star = star;
}
@Override
public void sign() {
star.sign();
}
}
import com.sfq.action.Agent;
import com.sfq.action.Singer;
import com.sfq.impl.IStar;
public class Idolater {
public static void main(String[] args) {
//要签名的明星
IStar star = new Singer();
//找到经纪人
Agent agent = new Agent(star);
System.out.println("能给我签个名吗?");
agent.sign();
}
}
结果
能给我签个名吗?
签名:XXX
我们是找明星的经纪人签字,真实签字的是明星,经纪人只是把 这个请求传递给明星处理而已。
(2)装饰模式
些演员通过粉饰自己给观众一个好的印象。
public interface IStar {
public void act(); //演戏
}
//演员
import com.sfq.impl.IStar;
public class FreakStar implements IStar {
@Override
public void act() {
System.out.println("演出中:演技很拙劣!");
}
}
//抽象装饰类
public abstract class Decorator implements IStar {
private IStar star;
public Decorator(IStar star) {;
this.star = star;
}
@Override
public void act() {
this.star.act();
}
}
import com.sfq.impl.Decorator;
import com.sfq.impl.IStar;
public class HotAir extends Decorator {
public HotAir(IStar star) {
super(star);
}
public void act() {
System.out.println("演出前:吹牛逼,我啥都能演!");
super.act();
}
}
import com.sfq.impl.Decorator;
import com.sfq.impl.IStar;
public class Deny extends Decorator {
public Deny(IStar star) {
super(star);
}
public void act() {
super.act();
System.out.println("演出后:我说啥了?啥都没说!");
}
}
import com.sfq.action.Deny;
import com.sfq.action.FreakStar;
import com.sfq.action.HotAir;
import com.sfq.impl.IStar;
public class Client {
public static void main(String[] args) {
IStar freakStar = new FreakStar();
freakStar = new HotAir(freakStar);
freakStar = new Deny(freakStar);
System.out.println("-----来,大家看明星啦-----");
freakStar.act();
}
}
结果
-----来,大家看明星啦-----
演出前:吹牛逼,我啥都能演!
演出中:演技很拙劣!
演出后:我说啥了?啥都没说!
(3)适配器模式
替身,替身也是演员,在表演过程中代替演员演一些高难度、危险的片段。
public interface IStar {
public void act(String context); //演戏
}
import com.sfq.impl.IStar;
public class FilmStar implements IStar {
@Override
public void act(String context) {
System.out.println("明星演戏:" + context);
}
}
public interface IActor {
public void playact(String context); //普通演员演戏
}
import com.sfq.impl.IActor;
public class UnknownActor implements IActor {
@Override
public void playact(String context) {
System.out.println("普通演员:" + context);
}
}
//替身
import com.sfq.impl.IActor;
import com.sfq.impl.IStar;
public class Standin implements IStar {
private IActor actor;
public Standin(IActor actor) {
this.actor = actor;
}
@Override
public void act(String context) {
actor.playact(context);
}
}
这是一个通用的替身,哪个普通演员能担任哪个明星的替身是由导演决定的。如果是专用替身的话,直接让替身类继承一个普通演员类即可。
import com.sfq.action.FilmStar;
import com.sfq.action.Standin;
import com.sfq.action.UnknownActor;
import com.sfq.impl.IActor;
import com.sfq.impl.IStar;
public class director {
public static void main(String[] args) {
System.out.println("-----开始演戏-----");
IStar star = new FilmStar();
star.act("前15分钟,明星演");
IActor actor = new UnknownActor();
IStar standin = new Standin(actor);
standin.act("中间5分钟,替身演");
star.act("后15分钟,明星演");
}
}
结果
-----开始演戏-----
明星演戏:前15分钟,明星演戏
普通演员:中间5分钟,替身演
明星演戏:后15分钟,明星演
使用适配器模式,把一个普通的演员转换为一个明星。
(4)桥梁模式
目前的明星大都追求多元化发展,例如主持人出专辑、体育明星演电影、歌星拍戏等。
类中将明星与行为分开,分别进行定义。
//抽象活动
public abstract class AbsAction {
public abstract void desc(); //活动描述
}
import com.sfq.impl.AbsAction;
public class ActFilm extends AbsAction {
@Override
public void desc() {
System.out.println("演好看电影");
}
}
import com.sfq.impl.AbsAction;
public class Sing extends AbsAction {
@Override
public void desc() {
System.out.println("唱好听歌曲");
}
}
public abstract class AbsStar {
protected final AbsAction action; //明星参加活动
public AbsStar(AbsAction action) {
this.action = action;
}
//明星自己的工作
public void doJob() {
action.desc();
}
}
import com.sfq.impl.AbsAction;
import com.sfq.impl.AbsStar;
public class FilmStar extends AbsStar {
public FilmStar() {
super(new ActFilm());
}
public FilmStar(AbsAction action) {
super(action);
}
//细化电影明星职责
public void doJob() {
System.out.println("-----影星的工作-----");
super.doJob();
}
}
import com.sfq.impl.AbsAction;
import com.sfq.impl.AbsStar;
public class Singer extends AbsStar {
public Singer() {
super(new Sing());
}
public Singer(AbsAction action) {
super(action);
}
//细化歌星职责
public void doJob() {
System.out.println("-----歌星的工作-----");
super.doJob();
}
}
import com.sfq.action.ActFilm;
import com.sfq.action.FilmStar;
import com.sfq.action.Singer;
import com.sfq.impl.AbsStar;
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();
}
}
结果
-----影星的工作-----
演好看电影
-----歌星的工作-----
唱好听歌曲
-----歌星的工作-----
演好看电影
(5)门面模式
门面模式在之前讲的较多,大家可以翻看之前的文章,这里不做过多赘述。