使用转接头(适配器)

  前俩天老妈说从家里抽屉里找到个耳机但是用不了,我让她拍个照片给我看,原来是因为手机是Type-C接口,耳机是3.5mm头的。于是我买了个转接口给她。如下图:
在这里插入图片描述
  本能反应的我,立马开始联想了起来…


适配器
情景1 没有耳机

  mom的手机

public class MomPhone {

    private TypeC earphone;

    public void play(){
        if (earphone == null) {
            System.out.println("loudspeaker play");
        } else {
            System.out.println(earphone.getType() + " earphone play");
        }
    }

    public void connect(TypeC earphone){
        this.earphone = earphone;
    }
}

  播放状态是扬声器外放

MomPhone momPhone = new MomPhone();
momPhone.play(); // loudspeaker play
情景2 连接Type-C接口的华为耳机
public interface TypeC {
    String getType();
}

public class TypeCHW implements TypeC {
    @Override
    public String getType() {
        return "Huawei";
    }
}

  播放状态是华为耳机播放

momPhone.connect(new TypeCHW());
momPhone.play(); // Huawei earphone play
情景3 连接3.5mm的JBL耳机
public interface M35 {
    String getType();
}

public class M35JBL implements M35 {
    @Override
    public String getType() {
        return "JBL";
    }
}

  接口不对应是不能使用的,所以需要一个如图的转接头

public class Adapter implements TypeC{

    private M35 m35;

    public Adapter(M35 m35) {
        this.m35 = m35;
    }

    @Override
    public String getType() {
        return m35.getType();
    }
}

  转接头需要连接手机,所以必须实现Type-C接口,并且暴露一个3.5mm接口,让3.5mm的设备连接自己,就是Adapter的构造方法。
  有了转接口就可以播放了

momPhone.connect(new Adapter(new M35JBL()));
momPhone.play(); // JBL earphone play
适配器模式

  情景3中将3.5mm设备通过转接口连接上Type-C接口的设备的过程,就是使用了设计模式中适配器模式,那个转接头就是适配器。
  适配器模式可以分为类适配、对象适配、接口适配,上面用的就是对象适配。

类适配
public class M35JBLAdapter extends M35JBL implements TypeC {
    @Override
    public String getType() {
        return super.getType();
    }
}

  要描述上面这个类,可以理解JBL的厂商将原来的JBL耳机升级为Type-C接口一样,是专门针对M35JBL这款设备做了适配一样。

momPhone.connect(new M35JBLAdapter());
momPhone.play(); // JBL earphone play
接口适配

  这种模式在业务代码中应该很少遇到。大致描述就是说,有一个接口中定义了很多方法,如果想只实现其中部分的话,可以在接口和实现类中增加一层抽象类,抽象类实现接口所有方法,但是都是空实现,自定义类继承抽象类可以重写其中部分方法。

public interface A {
    void a();
    void b();
    void c();
    void d();
    void e();
    void f();
    void g();
    void h();
}
public abstract class AbstractA implements A {
    public void a() {}
    public void b() {}
    public void c() {}
    public void d() {}
    public void e() {}
    public void f() {}
    public void g() {}
    public void h() {}
}
public class AImpl extends AbstractA {
    public void b() {
        System.out.println();
    }
    public void e() {
        System.out.println();
    }
}

  其中的AbstractA类就是适配器。

策略模式

  策略模式大多情况用在根据不同角色(或类型)处理不同业务的场景中(比如游客、VIP、活动送的VIP)。举个例子:

		if ("tourists".equals(type)) {
            // 业务a
        } else if ("vip".equals(type)) {
            // 业务a
        } else if ("presenterVip".equals(type)) {
            // 业务a
        } else {
            // 业务a
        }

  随着业务代码行数比较多的时候,将每个业务代码提成一个单独的方法,可读性很高。直到增加了一个为 SVIP 的类型,原来的业务方法可能也需要拆分,于是决定将每个方法都独立成一个类。
在这里插入图片描述

public interface Role {
    void run();
}

public class VIP implements Role {
    @Override
    public void run() {
        // vip
    }
}

public class SVIP implements Role {
    @Override
    public void run() {
        // 金主爸爸,什么权限都开
    }
}

public class Tourists implements Role {
    @Override
    public void run() {
        // 穷b,不需要操作
        return;
    }
}

public class PVIP implements Role{
    @Override
    public void run() {
        // 活动送的vip,只设置头像挂饰
    }
}

  另外定义一个业务类,将业务方法抽取出来

public class RoleService {

    private Role role;

    public RoleService(Role role){
        this.role = role;
    }

    public void run(){
        role.run();
    }
}

  最初的调用方式变成了下面这样:

		Role role = null;
        if ("tourists".equals(type)) {
            role = new Tourists();
        } else if ("vip".equals(type)) {
            role = new VIP();
        } else if ("presenterVip".equals(type)) {
            role = new PVIP();
        } else if ("svip".equals(type)){
            role = new SVIP();
        }
        RoleService roleService = new RoleService(role);
        roleService.run(); // 业务a

  如果再次增加一种类型,同样执行业务a,那么扩展Role接口的实现类即可(程序设计开闭原则:对扩展开放,对修改关闭),以上改进流程就是运用了策略设计模式。每种角色有单独的实现类后,其中只包含该角色应该要做的业务,不和其他角色业务混在一起(单一职能原则),降低业务间的耦合。
  但是貌似这么多if-else还是没有删除,还是要修改if-else内容。其实这块代码可以抽象成工厂方法,需要根据type获取对应角色实现类,用在程序其他地方。

简单工厂模式
public class RoleFactory {
    
    public static Role create(String type) {
        if ("tourists".equals(type)) {
            return new Tourists();
        } else if ("vip".equals(type)) {
            return new VIP();
        } else if ("presenterVip".equals(type)) {
            return new PVIP();
        } else if ("svip".equals(type)){
            return new SVIP();
        } else {
            throw new RuntimeException("Type Error");
        }
    }
}

  使用简单工厂

        Role role = RoleFactory.create(type);
        RoleService roleService = new RoleService(role);
        roleService.run(); // 业务a
最后

  刚开始写代码的时候并不知道设计模式有什么用,感觉花里胡哨还把自己绕晕了,直到在多个项目中由于需求的增加,发现自己写的代码改起来越来越费劲,慢慢的重构改进后,有一天发现自己原来用了设计模式(第一个是策略模式)。那么下次遇到这种业务场景,开始就按一种模式设计后,不论是后期优化还是扩展都很方便,而且代码的可读性也很好。
  每个人对设计模式态度是不一样的,站的高度不同,看法也不同。“看山是山,看水是水;看山不是山,看水不是水;看山还是山,看水还是水”。不知道自己何时能修炼到那个境界。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值