通过粘附Cactoos原沐鸣测速登录地址语延迟加载和缓存

你显然知道什么是延迟加载,对吧?您肯定了解缓存。据我所知,在Java中没有优雅的方法来实现它们。以下是我在仙人掌原始人的帮助下自己发现的。
《现实》(Reality, 2012),沐鸣测速登录地址马泰奥·加罗内(Matteo GarroneReality)著(2012)
假设我们需要一个对象来加密一些文本。以一种更面向对象的方式来说,它将封装文本并成为其加密的形式。下面是我们将如何使用它(让我们先创建测试):
接口加密{
asString()抛出IOException;
}
enc = new EncryptedX(“Hello, world!”);
System.out.println (enc.asString ());
现在让我们以一种非常原始的方式实现它,使用一个主构造函数。加密机制将在传入数据的每个字节中添加+1,并假设加密不会破坏任何东西(一个非常愚蠢的假设,但为了这个例子,它会工作):沐鸣注册平台
类Encrypted1实现加密{
私有最终字符串文本;
Encrypted1(字符串txt) {
这一点。文本=三种;
}
@Override
公共字符串asString() {
最后一个字节[]in = this.text.getBytes();
final byte[] out = new byte[in.length];
for (int i = 0;我< in.length;+ + i) {
out[i] = (byte) (in[i] + 1);
}
返回新字符串(出);
}
}
看起来正确吗?我测试了一下,效果不错。如果输入是“Hello, world!”,输出将是“Ifmmp-!xpsme\”。
接下来,让我们假设我们想让类接受一个InputStream和一个字符串。我们想这样称呼它,例如:
enc = new Encrypted2(
新FileInputStream (“/ tmp / hello.txt”)
);
System.out.println (enc.toString ());
下面是最明显的实现,有两个主构造函数(同样,实现是基本的,但是可以工作):
类Encrypted2实现加密{
私有最终字符串文本;
Encrypted2(InputStream input)抛出IOException {
ByteArrayOutputStream包=
新ByteArrayOutputStream ();
而(真){
int one = int .read();
if (1 < 0) {
打破;
}
baos.write(一);
}
这一点。text =新字符串(baos.toByteArray());
}
Encrypted2(字符串txt) {
这一点。文本=三种;
}
// asString()与Encrypted1中的完全相同
}
从技术上讲,它是可行的,但是流读取就在构造函数内部,这是一种不好的做法。主构造函数只能执行属性赋值,而次构造函数只能创建新对象。沐鸣平台
让我们尝试重构和引入延迟加载:
类Encrypted3实现加密{
私人字符串文本;
私有最终输入流;
Encrypted3 (InputStream流){
这一点。文本=零;
这一点。输入=流;
}
Encrypted3(字符串txt) {
这一点。文本=三种;
这一点。输入=零;
}
@Override
公共字符串asString()抛出IOException {
如果这一点。text == null) {
ByteArrayOutputStream包=
新ByteArrayOutputStream ();
而(真){
int one = int .read();
if (1 < 0) {
打破;
}
baos.write(一);
}
这一点。text =新字符串(baos.toByteArray());
}
最后一个字节[]in = this.text.getBytes();
final byte[] out = new byte[in.length];
for (int i = 0;我< in.length;+ + i) {
out[i] = (byte) (in[i] + 1);
}
返回新字符串(出);
}
}
效果很好,但是看起来很丑。最丑陋的部分当然是这两行:
这一点。文本=零;
这一点。输入=零;
它们让对象可变,并使用NULL。它很丑,相信我。不幸的是,在经典的例子中,延迟加载和空引用总是同时出现。然而,有一个更好的方法来实现它。让我们重构我们的类,这次使用Cactoos中的标量:
类Encrypted4实现加密{
私有最终IoCheckedScalar text;
Encrypted4 (InputStream流){
这个(
()- > {
ByteArrayOutputStream包=
新ByteArrayOutputStream ();
而(真){
int one = stream.read();
if (1 < 0) {
打破;
}
baos.write(一);
}
返回新字符串(baos.toByteArray ());
}
);
}
Encrypted4(字符串txt) {
(()- > txt);
}
Encrypted4(标量<字符串>源){
这一点。text = new IoCheckedScalar<>(源);
}
@Override
公共字符串asString()抛出IOException {
最后一个字节[]in = this.text.value().getBytes();
final byte[] out = new byte[in.length];
for (int i = 0;我< in.length;+ + i) {
out[i] = (byte) (in[i] + 1);
}
返回新字符串(出);
}
现在看起来好多了。首先,只有一个主构造函数和两个辅助构造函数。其次,对象是不可变的。第三,仍然有很大的改进空间:我们可以添加更多的构造函数,这些构造函数将接受其他数据源,例如文件或字节数组。