方法屏蔽之lambda方式

设计模式 同时被 2 个专栏收录
3 篇文章 0 订阅
87 篇文章 1 订阅
利用lambda特性,隐藏类中的method,
有两个优点:
* 1.屏蔽无关方法
* 2.被调用方法对调用方彻底透明
import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class MethodHideWithLambda {
    static class F {
        public void foo() {
            System.out.println("===foo===");
        }

        public void foo1() {
            System.out.println("===foo===");
        }

        public void foo2() {
            System.out.println("===foo===");
        }
    }

    public static void main(String[] args) throws IOException {
        List<F> fList = Arrays.asList(new F(), new F());
        Iterator<Closeable> iterator = fList.stream().map(f -> (Closeable) f::foo).iterator();
        iterator.next().close();
    }
}

这段代码的运行结果: 

===foo===

调用的是close方法,实际执行的是foo方法。

那不禁要产生疑问:foo返回值是void,为什么f::foo能强制转换成Closeable?

因为f::foo这种静态推导,它返回的是FunctionalInterface,这是一个匿名的函数。

这个函数的特点是:没有参数,没有返回值。

它强转的不是f本身,它强转的是匿名函数,所以可以把它定义成任意的没有返回值没有入参的接口。

下面代码也是这种情况:

Closeable closeable = () -> System.out.println("====");
Runnable runnable = () -> System.out.println("====");

所以,强转成Runnable也可以,甚至自定义一个接口:

//例如:
interface Fuzz {
    void test();
}
Iterator<Fuzz> iterator = fList.stream().map(f -> (Fuzz) f::foo).iterator();

//例如:
Iterator<Runnable> iterator = fList.stream().map(f -> (Runnable) f::foo).iterator();

又有另外一个疑问,为什么要这样做呢?fList.iterator()就行了呀

假设:返回的迭代器是要给别人调用的。等别人通过迭代器拿到对象,还能调用到foo1和foo2方法。

但你不想暴露这两个方法,怎么办?

这里转成Closeable,它只有一个close方法,调用close方法时,真正执行的是foo方法。

这样就相当于把foo1和foo2给屏蔽掉了,起到一个封装的作用。

对调用方完全透明,调用方甚至不知道有foo方法,透明的非常彻底。 

这可以是作为一种编程最佳实践来看吧。

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值