Ily*_*tov 1 java design-patterns hashmap
我有一个简单的应用程序,它接受一个字符串并返回字符串中唯一字符的数量。预计一个字符串可能会多次传递给该方法。该方法应该缓存结果,以便在给该方法之前遇到的字符串时,它会检索存储的结果。
出于学习目的,我需要使用装饰器模式来实现缓存。我从网上学到的:
public interface CharCount {
Map<String, Long> charCount(String input);
}
Run Code Online (Sandbox Code Playgroud)
public class CharCountImplement {
Map<String, Long> charCount(String input) {
return Arrays.stream(input.split(""))
.collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting()));
}
}
Run Code Online (Sandbox Code Playgroud)
public abstract class Decorator implements CharCount {
private CharCount charCount;
@Override
public Map<String, Long> charCount(String input) {
return charCount.charCount(input);
}
}
Run Code Online (Sandbox Code Playgroud)
public class CachedDecorator extends Decorator {
// decorator must contain something else
public Map<String, Long> charCount(String input) {
// some decoration code - no problem with it
return super.charCount(input);
}
}
Run Code Online (Sandbox Code Playgroud)
我不太明白这种设计模式的原理,以及如何在我的情况下使用它。我看过/阅读了许多关于披萨和咖啡装饰师的教程,但没有帮助。
要使用缓存装饰 CharCount 对象,您可以使用以下内容:
public class CachedDecorator extends Decorator {
// NOTE: you don't realy need the abstract class Decorator
// you could also put the `private CharCount charCount;` into this class and let it implement CharCount instead of extending Decorator
// then you need to replace super.charCount(input) by charCount.charCount(input) in the charCount method in this class (the line is marked below)
private Map<String, Map<String, Long>> cache = new HashMap<>();
public CachedDecorator(CharCount charCount) {
this.charCount = charCount;//the base object that you are decorating
}
public Map<String, Long> charCount(String input) {
// --- start of the additional, decorating implementation
//check whether the input string was already processed and is cached
Map<String, Long> cached = cache.get(input);
if (cached != null) {
//we already know the solution, so just return it without calculating
return cached;
}
// --- call the super implementation that was decorated (where the super implementation in Decorator calls the charCount method of the CharCount object, that was added in the constructor of this class
Map<String, Long> calculated = super.charCount(input); //here you may also use charCount.charCount(input); instead of super.charCount(input); (see the NOTE in the top of this class)
// --- cache the result (again a decoration of the implementation)
cache.put(input, calculated);
// return the result
return calculated;
}
}
Run Code Online (Sandbox Code Playgroud)
使用缓存的装饰器,您可以执行以下操作:
CharCount simpleCharCount = new CharCountImplement();
CharCount cachingCharCount = new CachedDecorator(simpleCharCount);
simpleCharCount.charCount("Hello World!");// this will just calculate the result, because it's the simple object without cache
simpleCharCount.charCount("Hello World!");// the result is calculated another time
cachingCharCount.charCount("Hello World!");// this will use the simpleCharCount object to calculate the result map of "Hello World!" once
cachingCharCount.charCount("Hello World!");// this time the result is not calculated but just taken from the cache
Run Code Online (Sandbox Code Playgroud)
与仅仅创建另一个实现相比,装饰器模式的优势在于您不必在CharCountImplement
类中重新实现代码,而只需重复使用它即可。也可以CacheDecorator
在每个需要 a 的地方使用CharCount
。因此,如果您有一个方法,它需要一个CharCount
对象作为参数并且正在使用一个CharCountImplement
对象,您可以简单地使用CacheDecorator
代替,而无需更改您正在调用的方法中的任何代码。
在这种情况下,您还可以创建一个扩展CharCountImplement
以实现相同效果的类。但是如果你想创建CharCount
接口的另一个实现并且让这个新实现也使用缓存,装饰器模式可以为你节省很多工作,因为你不需要为 的每个实现创建这个缓存子类CharCount
,但是你可以只为 . 的每个实现使用一个装饰器CharCount
。
因此,如果您有 4 个实现,则CharCount
可以使用 4 个子类来实现缓存,或者仅使用 1 个装饰器。如果您想使用另一个装饰器,这种效果会呈指数级增长,因此这种模式对于减少您需要创建的类数量并保持代码DRY 非常有帮助。
归档时间: |
|
查看次数: |
110 次 |
最近记录: |