结构型设计模式

1.代理模式

定义:为其他对象提供一种代理以控制对这个对象的访问
1.1简单实现静态代理
定义个购买的接口
public interface IShop {
    void buy();
}

我这个人 需要购买
public class LiuWangShu implements IShop {
    @Override
    public void buy() {
        System.out.println("购买");
    }
}

这个人就是代理人 谁进来我就可以给他购买 像代购
public class Purchasing implements IShop {
    private IShop mShop;

    Purchasing(IShop shop) {
        mShop = shop;
    }

    @Override
    public void buy() {
        mShop.buy();
    }
}

我只要打个电话给代购 让他帮我买东西 它就帮我买了实现静态代理
public class Client {
    Client() {
        LiuWangShu liuWangShu = new LiuWangShu();
        Purchasing purchasing = new Purchasing(liuWangShu);
        purchasing.buy();
    }
}

1.2 接下来我们看一下动态代理
实现InvocationHandler接口在动态 最终会执行invoke方法
public class DynamicPurchasing implements InvocationHandler {
    private Object obj;
    DynamicPurchasing(Object obj) {
        this.obj = obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object result = method.invoke(obj, args);

        if (method.getName().equals("buy")) {
            System.out.println("买买买");
        }
        return result;
    }
}

在创建一个这个对象DynamicPurchasing 然后拿到liuWangShu这个类,最后在调用代理模式的newProxyInstance方法生产一个对象 然后调用对象方法

public class Client {
    Client() {
        LiuWangShu liuWangShu = new LiuWangShu();
        Purchasing purchasing = new Purchasing(liuWangShu);
        purchasing.buy();


        DynamicPurchasing dynamicPurchasing = new DynamicPurchasing(liuWangShu);
        ClassLoader classLoader = liuWangShu.getClass().getClassLoader();
        IShop mIshop = (IShop) Proxy.newProxyInstance(classLoader, new Class[]{IShop.class}, dynamicPurchasing);
        mIshop.buy();

    }
}
1.3 优点解析
(1)主题类是实现业务逻辑,不用关心其他非本职工作
(2)主题类随时会发生改变,但因为它实现了公共的接口,所以代理类不做任何改变就可以使用
1.4 总结
代理模式分为静态代理和动态代理,静态代理说白了就调用你这个对象的已有方法,只不过通过应用传递给别人去调用了。动态代理其实就是通过java的动态代理机制去实现具体的方法,只是需要注意动态代理的各个参数和使用规则

2.装饰模式

定义:动态地给一个对象添加额外的职责,就增加功能来说,装饰模式比生成子类更加灵活
2.1 简单实现
这个是一个普通人

public abstract class Swordsman {

    public  abstract void attackMagic();
}

普通人一开始只有剑术
public class YangGuo extends Swordsman{


    @Override
    public void attackMagic() {
        System.out.print("学习过剑术");
    }
}

定义一个高手 谁传进来就教授武功
public abstract class Master extends Swordsman {

    private Swordsman mSwordsman;

    public Master(Swordsman mSwordsman) {
        this.mSwordsman = mSwordsman;
    }

    public void attackMagic() {
        mSwordsman.attackMagic();
    }
}
洪七公是具体高手的实现 只有有人来就可以教授武功

public class HongQiGong extends Master {

    public HongQiGong(Swordsman mSwordsman) {
        super(mSwordsman);
    }

    @Override
    public void attackMagic() {
        super.attackMagic();
        teachWuGong();
    }

    private void teachWuGong() {
        Log.i("HongQiGong", "teachWuGong: 教授新武功");
    }
}
洪七公实现了方法教授了武功
public class Client {

    Client(){
        YangGuo yangGuo = new YangGuo();
        HongQiGong hongQiGong = new HongQiGong(yangGuo);
        hongQiGong.attackMagic();
    }
    
}
2.2使用场景
(1)在需要不影响对象定义情况下,以动态,透明的方式给单个对象添加职责。
(2)需要动态给对象增加功能,这些功能需要可以撤销的时候
2.3 优点
(1)通过装饰者,可以动态扩展一个对象的功能,在运行时候选择不同的装饰器,实现不同的行为
(2)有效避免了使用继承方式对对象功能带来的灵活性差,子类无限扩展问题。
(3)具体组件和具体装饰类可以独立变化,用户可以根据需要增加和新的组件类和装饰类,在使用的时候进行组合,原来代码可以不用改变
2.4 总结
装饰者就是先自己定义个类然后有个装饰类,将具体类传入装饰类中,在装饰类中做更多的处理操作,不同的装饰类可以有不同的操作

3.外观模式

定义:要求一个子系统的外部与内部的通信必须通过一个统一的对象进行。此模式提供一个统一高层模式,让子系统更加容易使用。
3.1 具体代码
定义一个招式系统
public class ZhaoShi {
    public void TaiJiQuan(){
     System.out.print("使用招式太极拳");
    }

    public  void QiShangQuan(){
        System.out.print("使用招式七伤拳");

    }

    public  void ShenHuo(){
        System.out.print("使用招式圣火令");
    }
    
}

定义一个内功系统
public class NeiGong {
   public void JiuYang(){
        System.out.print("使用九阳神功");
    }
    public void QianKun(){
        System.out.print("使用乾坤大挪移");
    }
}
定义一个系统 这个系统会直接协调出招式的时候要怎么样调用其他武功系统,最后把结果处理好
public class ZhangWuJi {
    private ZhaoShi zhaoShi;
    private NeiGong neiGong;
    public ZhangWuJi() {
        zhaoShi = new ZhaoShi();
        neiGong = new NeiGong();
    }
    public void QiShangQuan() {
        neiGong.JiuYang();
        zhaoShi.QiShangQuan();
    }
}
客户端调用只需要说 我要哪个招式
public class Client {
    public Client() {
        ZhangWuJi zhangWuJi = new ZhangWuJi();
        zhangWuJi.QiShangQuan();
    }
}
3.2外观模式的使用场景和优缺点
(1)使用场景
构建一个有层次的子系统,使用外观欧式定义子系统每层,减少子系统之间相互依赖关系
外观模式提供一个简单的接口,对外隐藏子系统的具体实现并隔离变化,调用者非常简单,不需要知道内部子系统的实现细节
(2)优点
减少系统的相互依赖。所有的依赖都在外观类
对用户隐藏了子系统的实现,减少用户对子系统的偶合,就算子系统变化了,用户也不会感知到
加强了安全性,子系统不在如果不在外观类中开通,就无法访问到子系统的方法。
(3)缺点
如果子系统发生改变,那么可能要修改外观类
3.3总结
其实外观模式就是一个类它会协调很多子系统,然后对外提供一个很简单的方法给用户去使用,用户不需要知道外观类具体是怎么协调子系统之间进行工作的,比如很多开源框架就是这样子干的。

4 享元模式

定义使用共享对象有效支持大量细粒度的对象
4.1代码实现
先定义个实体类
public class Goods implements IGoods {
    private String name;
    private String version;


    Goods(String name) {
        this.name = name;

    }

    @Override
    public void showGoodsPrice(String version) {
        if (version.equals("32G")) {
            System.out.print("价格为5199");
        } else {
            System.out.print("价格为5999");
        }
    }
}

定义一个享元工厂
public class GoodsFactory {
    private static Map<String, Goods> pool = new HashMap<String, Goods>();

    public static Goods getGoods(String name) {

        if (pool.containsKey(name)) {
            System.out.print("使用缓存 key为" + name);
            return pool.get(name);
        } else {
            Goods goods = new Goods(name);
            pool.put(name, goods);
            System.out.print("创建商品,key为" + name);
            return goods;
        }
    }

}
最后使用享元模式
public class Client {

    Client(){
        Goods iphone7 = GoodsFactory.getGoods("iphone7");
        iphone7.showGoodsPrice("32");
        Goods iphone8 = GoodsFactory.getGoods("iphone7");
        iphone8.showGoodsPrice("32");
    }
}

会发现只有第一次创建了 其他时候都是使用缓存的对象
4.2 使用场景及优缺点
系统中存在大量相似的对象
需要缓存池的场景
4.3 总结
其实所谓享元模式就是存在一个map 将对象存储进去,没有的话就创建一个存储进去,如果有的话直接返回回去。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值