结构类模式大PK
结构类模式包括适配器模式、桥梁模式、组合模式、装饰模式、门面模式、享元模式和代理模式。
为什么叫结构类模式呢?因为他们都是通过组合类或对象产生更大结构以适应更高层次的逻辑需求。
1.代理模式 VS 装饰模式
装饰模式就是代理模式的一个特殊应用,两者的共同点是都具有相同的接口,不同点则是代理模式着重对代理过程的控制,而装饰模式则是对类的功能进行加强或减弱,它着重类的功能变化。
//抽象运动员
public interface IRunner {
public void run();
}
//运动员跑步
public class Runner implements IRunner {
public void run(){
System.out.println("运动员跑步:动作很潇洒");
}
}
//代理模式:代理人
public class RunnerAgent implements IRunner {
private IRunner runner;
public RunnerAgent(IRunner runner) {
this.runner = runner;
}
//代理人控制被代理人行为
public void fun() {
Random rand = new Random();
if(rand.nextBoolean()) {
System.out.println("代理人同意安排运动员跑步");
runner.run();
}else {
System.out.println("代理人心情不好,不安排运动员跑步");
}
}
}
//场景类
public class Client {
public static void main(String[] args) {
IRunner liu = new Runner();
IRunner agent = new RunnerAgent(liu);
agent.run();
}
}
//装饰模式:装饰类
public class RunnerWithJet implements IRunner {
private IRunner runner;
public RunnerWithJet(IRunner runner) {
this.runner = runner;
}
public void run() {
System.out.println("加快运动员的速度:为运动员增加喷气装置");
runner.run
}
}
//场景类
public class Client {
public static void main(String[] args) {
IRunner liu = new Runner();
liu = new RunnerWithJet(liu);
liu.run();
}
}
代理模式是把当前的行为或功能委托给其他对象执行,代理类负责恩接口限定:是否可以调用真是角色,以及是否对发送到真是角色的消息进行变形处理,它不被主题角色的功能做任何处理,保证原滋原味的调用。代理模式使用到极致开发就是AOP,这是采用Spring架构开发必然要使用到的技术。
装饰模式是在要保证接口不变的情况下加强类的功能,它保证的是被修饰的对象功能比原始对象丰富(或减弱),但不做准入条件判断和准入参数过滤,如是否可以在执行类的功能,过滤输入参数是否合规等,这不是装饰模式关心的。
2.装饰模式 VS 适配器模式
装饰模式和适配器模式在通用类图上没有太多的相似点,但是它们的功能有相似的地方:都是包装作用,都是通过委托方式实现其功能。
不同点是:装饰模式包装的是自己的兄弟类,隶属于同一个家族,适配器模式则修饰非血缘关系类,把一个非本家族的对象伪装成本家族的对象,它的本质还是非相同接口的对象,但是可用相同抽象类或接口声明引用。
意图不同
装饰模式的意图是加强对象的功能,不改变类的属性和行为。
适配器模式关注的则是两个不同对象之间的转化。
施与对象不同
装饰模式装饰的对象必须是自己的同宗,也就是相同的接口或父类。
适配器模式则必须是两个不同的对象,因为它着重于转换。
场景不同
装饰模式在任何时候都可以使用,只要是向增强类的功能。
适配器模式则是一个补救模式,一般出现在系统成熟或已经构建完毕的项目中,作为一个紧急处理手段使用。
扩展性不同
装饰模式很容易扩展,并且可以继续扩展下去。
适配器模式在两个不同对象之间架起一座沟通的桥梁,建立容易,去掉就比较困难了,需要从新系统整体考虑是否能够撤销。
####适配器实现替身演员
//明星接口
interface IStar{
//明星都要演戏
public void act(String context);
}
//电影明星
class FilmStar implements IStar{
public void act(String context){
System.out.println("明星演戏:"+context);
}
}
//普通演员接口
interface IActor{
//普通演员演戏
public void playact(String context);
}
//普通演员
class UnknownActor implements IActor{
public void playact(String context){
System.out.println("普通演员:"+context);
}
}
//替身演员
class Standin implements IStar{
private IActor actor;
//替身是谁
public Standin(IActor actor){
this.actor = actor;
}
public void act(String context){
actor.playact(context);
}
}
//导演类
public class direcotr{
publoc staticvoid mian(String[] args){
//定义一个大明星
IStar star= new FilmStar();
star.act("前十五分钟,明星本人在演戏");
//导演把一个普通演员当做明星演员来用
IActor actor = new UnknownActor();
IStar standin = new Standin(actor);
standin.act("中间五分钟,替身在演戏");
star.act("后十五分钟,明星本人演戏");
}
}