浅谈设计模式(三)

一、适配器模式

目的:将某个类的接口转换成某个期望接口的的标识,主要是为了兼容性的目的,属于结构性模式。适配器让原本接口不兼容的类 可以合作无间。

1. 类的适配器

现在有一个接口和一个类

public interface Voltage5V {
    public int getVoltageBy5();
}

public class Voltage220V {
    public int getVoltageBy220(){
        return 220;
    }
}

适配类将两个进行适配

// 适配类 需要对适配的两种东西进行继承或者实现
public class AdapterPattern extends Voltage220V implements Voltage5V{
    @Override
    public int getVoltageBy5() {
        int src = this.getVoltageBy220();  // 实现接口的方法,并调用继承类的方式
        int dest = src - 110;  // 进行某种操作转换
        return dest;
    }
}

写一个调用的方法,表面上这个类是需要Voltage5V,我们可以将适配器传进去。

public class Phone {
    public void charging(Voltage5V voltage){
        System.out.println(voltage.getVoltageBy5());
    }
}

// 主函数进行调用
Phone phone = new Phone();
phone.charging(new AdapterPattern()); // 把适配器传进去  相当于插在了转换口上

2. 对象适配器

在类的适配上修改了耦合高的特点,将继承转变成了组合的形式。

public class IphoneAdapter implements Voltage5V{
    private Voltage220V voltage;  // 转变成组合的模式

    public IphoneAdapter(Voltage220V voltage){
        this.voltage = voltage;
    }

    @Override
    public int getVoltageBy5() {
        int src = voltage.getVoltageBy220();
        int dest = src - 110;
        return dest;
    }
}

main函数进行调用

Phone phone = new Phone();
phone.charging(new IphoneAdapter(new Voltage220V())); // 要适配 这样更灵活

3. 接口适配器

不想将所有的方法进行重写,只重写自己需要的方法。

用一个抽象类去实现接口中的所有方法,再用目标类进行继承抽象类,重写自己关心的方法。

public interface SrcInterface {
    public void func1();
    public void func2();
    public void func3();
    public void func4();
}

public abstract class DestClass implements SrcInterface{
    public void func1() {}
    public void func2() {}
    public void func3() {}
    public void func4() {}
}


// 主函数调用
DestClass destClass = new DestClass() { // 可以有选择的覆盖父类的子类
    @Override
    public void func1() {
        System.out.println("----");
    }
};

destClass.func1();

TIPS:适配器模式应用的时候一般通过 循环判断 instanceof 是否属于当前适配类的情况。

二、桥接模式

桥接模式实现了 实现部分和抽象放在两个不同类的层次中使两个层次可以独立转变,属于结构型设计模式,基于类的最小设计原则,其目的是减少子类的个数(针对类爆炸的问题),替代多层继承的方案。主要解决是一对一的模式。

比如点茶水情况,有茶的种类和是否加料的两个维度。便可以将这两个维度独立开来。

加料的维度:需要一个接口,和具体实现

public interface Material {
    public void addSth(String teaType);
}

public class Sugar implements Material{
    @Override
    public void addSth(String teaType) {
        System.out.println(teaType + "添加了糖");
    }
}

public class Milk implements Material{
    @Override
    public void addSth(String teaType) {
        System.out.println(teaType + "添加了牛奶");
    }
}

茶的种类维度,和加料的接口是组合的方式,具体的茶种类的实现都需要继承ITea即可。

public abstract class ITea {
    private Material material;

    public ITea(Material material){
        this.material = material;
    }

    public abstract void orderTea(int count);

    public void addSth(String teaType){
        this.material.addSth(teaType);
    }
}

public class Tea extends ITea{
    public Tea(Material material) {
        super(material);
    }

    @Override
    public void orderTea(int count) {
        System.out.println("点了"+count+"杯茶水");
    }

    @Override
    public void addSth(String teaType) {
        super.addSth(teaType + "普通茶");
    }
}

三、装饰者模式

装饰者模式主要目的是 动态的将新功能附加到对象上,在对象功能扩展方面,比继承更有弹性。相比桥接模式可以是一对多模式。

 首先这个抽象类有一个基本方法,凡是继承了食物这个接口的所有类都必须重写这个接口。

// 抽象的基类
public abstract class Food {
    public String name;
    public int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public abstract int calCost();  // 抽象方法供子类实现
}

具体的食物就继承这个类。

public class Jianbing extends Food{
    public Jianbing(){
        setName("煎饼果子");
        setPrice(4);
    }

    @Override
    public int calCost() {
        return super.getPrice();
    }
}

public class ShaoBing extends Food{
    public ShaoBing(){
        setName("泰山烧饼");
        setPrice(1);
    }

    @Override
    public int calCost() {
        return super.getPrice();
    }
}

装饰对象抽象相当于做一个通用的包装接口,后续的包装类只需要继承这个抽象类,然后再在其中加入新的行为或属性即可,而不需要重复封装。装饰类既继承又组合,这是装饰者模式的标志

public abstract class FoodDecorator extends Food{
    Food food;

    public FoodDecorator(Food food){
        this.food = food;
    }
}

装饰者实现

public class Egg extends FoodDecorator{
    public Egg(Food food) {
        super(food);
        setName("蛋蛋");
        setPrice(2);
    }

    @Override
    public int calCost() {
        return food.calCost() + super.getPrice();  // food.calCost 是递归
    }
}

public class Suggest extends FoodDecorator{
    public Suggest(Food food) {
        super(food);
        setName("烤肠");
        setPrice(3);
    }

    @Override
    public int calCost() {
        return food.calCost() + super.getPrice();  // food.calCost 是递归
    }
}

主函数调用

Food jianbing = new Jianbing();
System.out.println(jianbing.price);
Food egg = new Egg(jianbing);
System.out.println(egg.calCost());
Suggest suggest = new Suggest(egg);
System.out.println(suggest.calCost());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值