美文网首页
装饰模式与代理模式的异同

装饰模式与代理模式的异同

作者: 努力做一个最懒的程序员 | 来源:发表于2018-10-30 17:47 被阅读0次

一、装饰模式

1.定义:

    动态地给一个对象添加一些额外的职责。(就增加功能来说,装饰模式生成子类更为灵活)

2.使用场景:

    需要透明且动态地扩展类的功能。

3.安卓实例:

    Context、ContextImpl、ContextWrapper。

4.例子:

UML
/**
 * 角色
 */
interface Role {

    void decorate();
}

/**
 * 男性角色
 */
class MaleRole implements Role {

    @Override
    public void decorate() {
        System.out.println("初始化男性角色");
    }
}

/**
 * 装备
 */
abstract class Clothes implements Role {

    protected Role mRole;

    public Clothes(Role role) {
        mRole = role;
    }

    @Override
    public void decorate() {
        mRole.decorate();
    }
}

/**
 * 功能宝珠
 */
abstract class Gem implements Role {

    protected Role mRole;

    public Gem(Role role) {
        mRole = role;
    }

    @Override
    public void decorate() {
        mRole.decorate();
    }
}

/**
 * 玄铁甲
 */
class XuanTieJia extends Clothes {

    public XuanTieJia(Role role) {
        super(role);
    }

    @Override
    public void decorate() {
        System.out.println("穿上玄铁甲");
    }
}

/**
 * 火系宝珠
 */
class FireGem extends Gem {

    public FireGem(Role role) {
        super(role);
    }

    @Override
    public void decorate() {
        System.out.println("镶嵌火系宝珠");
    }
}

public class DecorationTest {

    public static final String TAG = DecorationTest.class.getSimpleName();

    public static void main(String[] args) {
        // 初始化角色
        Role role = new MaleRole();
        // 穿个玄铁甲
        XuanTieJia xuanTieJia = new XuanTieJia(role);
        // 给玄铁甲镶嵌个火系宝珠
        FireGem fireGem = new FireGem(xuanTieJia);
        fireGem.decorate();
    }
}

二、代理模式

1.定义:

    为其他对象提供一种代理以控制这个对象的访问。

2.使用场景:

    当无法或不想直接访问某个对象或访问某个对象困难的时候可以通过一个代理对象来间接访问。(为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口)

3.静态代理:

    (1)静态代理其实就是在程序运行之前,提前写好被代理方法的代理类,编译后运行。在程序运行之前,class已经存在。
    (2)安卓实例:IBinder、Binder、BinderProxy。
    (3)与观察者模式比较:静态代理是一对一的关系;观察者模式为一对多的关系。

4.动态代理:

    (1)动态代理主要是通过反射机制,在运行时动态生成所需代理的class。
    (2)安卓实例:Retorift。

4.例子:

UML
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Random;

interface Game {

    void play();
}

class LeagueOfLegends implements Game {

    @Override
    public void play() {
        System.out.println(getClass().getSimpleName() + "打野中");
    }
}

/**
 * 静态代理
 */
class LeagueOfLegendsProxy implements Game {

    private Game mGame;
    private String mUserName;
    private String mUserPwd;
    private boolean isLogin;

    LeagueOfLegendsProxy(Game game, String userName, String userPwd) {
        mGame = game;
        mUserName = userName;
        mUserPwd = userPwd;
    }

    @Override
    public void play() {
        if (login(mUserName, mUserPwd)) {
            System.out.println(getClass().getSimpleName() + "登陆成功");
            mGame.play();
            System.out.println(getClass().getSimpleName() + "游戏胜利");
            if (playAgain()) {
                play();
            } else {
                isLogin = false;
                System.out.println(getClass().getSimpleName() + "退出登陆");
            }
        } else {
            System.out.println(getClass().getSimpleName() + "登陆失败");
        }
    }

    private boolean login(String userName, String userPwd) {
        if (isLogin) {
            return true;
        } else {
            System.out.println(getClass().getSimpleName() + "正在登陆对方账户:" + mUserName);
            isLogin = new Random().nextInt(10) % 2 == 0;
        }
        return isLogin;
    }

    private boolean playAgain() {
        return new Random().nextInt(10) % 2 == 0;
    }
}

/**
 * 动态代理
 */
class DynamicProxyHandler implements InvocationHandler {

    private Game mGame;

    DynamicProxyHandler(Game Game) {
        mGame = Game;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(getClass().getSimpleName() + "准备代打");
        Object invoke = method.invoke(mGame, args);
        System.out.println(getClass().getSimpleName() + "代打成功");
        return invoke;
    }
}

public class ProxyTest {

    public static final String TAG = ProxyTest.class.getSimpleName();

    public static void main(String[] args) {
        // 静态代理使用
        new LeagueOfLegendsProxy(new LeagueOfLegends(), "LiuGuoQing", "qwer1234").play();
        // 动态代理使用
        DynamicProxyHandler handler = new DynamicProxyHandler(new LeagueOfLegends());
        Game proxyInstance = (Game) Proxy.newProxyInstance(LeagueOfLegends.class.getClassLoader(), LeagueOfLegends.class.getInterfaces(), handler);
        proxyInstance.play();
    }

}

三、两者比较

1.相同点:

    装饰模式中装饰者(Decorator)和被装饰者(Cafe)都实现同一个 接口;代理模式中代理类(Proxy Class)和真实处理的类(Real Class)都实现同一个接口。

2.区别:

    装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,但不对对象本身的功能进行增强。

相关文章

  • 装饰模式与代理模式的异同

    一、装饰模式 1.定义: 动态地给一个对象添加一些额外的职责。(就增加功能来说,装饰模式生成子类更为灵活) 2.使...

  • 适配器模式,装饰模式,代理模式异同

    菜鸟版JAVA设计模式—适配器模式,装饰模式,代理模式异同 一、概念 适配器模式,允许因为接口不兼容而不能在一起工...

  • java中的代理模式与装饰者模式的区别

    java中的代理模式与装饰者模式的区别 代理模式与装饰者模式看起来很像,都实现基础对象实现的接口,在其自身对象中都...

  • 动态代理

    先说静态代理,静态代理就是设计模式中的代理模式,形式上与装饰模式一致,但是涵义不同,装饰模式注重新加的修饰功能,代...

  • 09.代理模式和装饰模式的区别

    代理模式和装饰模式 代理模式UML代理模式类图 装饰模式UML装饰模式类图从类图来看,二者除了名称不同,几乎没有差...

  • 设计模式

    单利模式 代理模式 工厂模式 装饰者模式:

  • 适配器模式、装饰模式、代理模式的异同

    这三种设计模式同属于结构型模式,初学者乍一看可能难以分辨三者的区别。这里对三者之间的异同详细地探讨一下。 适配器模...

  • 代理模式与装饰模式

    两者的具有很大的相似性,两者的UML类图实现 几乎相同, 代理模式 装饰模式772134-201605272023...

  • 装饰模式与代理模式的区别

    在Gof的设计模式一书中,装饰模式(Decorator,又名Wrapper)与代理模式(Proxy,又名Surro...

  • 设计模式

    1.代理模式 静态代理; 动态代理: 2.工厂模式 3.装饰模式 4.观察者模式

网友评论

      本文标题:装饰模式与代理模式的异同

      本文链接:https://www.haomeiwen.com/subject/dsugtqtx.html