Метод Apply.process() получает любую разновидность Processor, применяет ее к Object, а затем выводит результат. Метод split() является частью класса String. Он получает объект String, разбивает его на несколько фрагментов по ограничителям, определяемым переданным аргументом, и возвращает String[]. Здесь он используется как более компактный способ создания массива String.
Теперь предположим, что вы обнаружили некое семейство электронных фильтров, которые тоже было бы уместно использовать с методом Apply. process():
// interfaces/filters/Waveform java package interfaces.filters.
public class Waveform {
private static long counter;
private final long id = counter++; public String toStringO { return "Waveform " + id. }
public class Filter {
public String nameO {
return getClassO getSimpleName().
}
public Waveform process(Waveform input) { return input; }
// interfaces/filters/LowPass java package interfaces filters,
public class LowPass extends Filter { double cutoff;
public LowPass(double cutoff) { this.cutoff = cutoff; } public Waveform process(Waveform input) {
return input; II Фиктивная обработка
}
} Hill ■ i nterfaces/fi 1ters/Hi ghPass.java package interfaces.filters;
public class HighPass extends Filter { double cutoff;
public HighPass(double cutoff) { this.cutoff = cutoff; } public Waveform process(Waveform input) { return input. } } ///.-
// interfaces/filters/BandPass java package interfaces filters;
public class BandPass extends Filter { double lowCutoff. highCutoff; public BandPass(double lowCut. double highCut) { lowCutoff = lowCut; highCutoff = highCut;
}
public Waveform process(Waveform input) { return input; } }
Класс Filter содержит те же интерфейсные элементы, что и Processor, но, поскольку он не является производным от Processor (создатель класса Filter и не подозревал, что вы захотите использовать его как Processor), он не может использоваться с методом Apply.process(), хотя это выглядело бы вполне естественно. Логическая привязка между Apply.process() и Processor оказывается более сильной, чем реально необходимо, и это обстоятельство препятствует повторному использованию кода Apply.process(). Также обратите внимание, что входные и выходные данные относятся к типу Waveform.
Но, если преобразовать класс Processor в интерфейс, ограничения ослабляются и появляется возможность повторного использования Apply.process(). Обновленные версии Processor и Apply выглядят так:
//: interfaces/interfaceprocessor/Processor.java package interfaces interfaceprocessor;
public interface Processor { String nameO;
Object process(Object input), } ///-
//. interfaces/interfaceprocessor/Apply.java package i nterfaces.i nterfaceprocessor, import static net mindview.util.Print.*:
public class Apply {
public static void process(Processor p. Object s) { print ("Using Processor " + p.nameO): print(p.process(s)):
}
} ///:-
В первом варианте повторного использования кода клиентские программисты пишут свои классы с поддержкой интерфейса:
//: interfaces/interfaceprocessor/StringProcessor.java package i nterfaces.i nterfaceprocessor; import java.util.*;
public abstract class StringProcessor implements Processor! public String nameO {
return getClassO getSimpleNameO;
}
public abstract String process(Object input); public static String s =
"If she weighs the same as a duck, she's made of wood"; public static void main(String[] args) { Apply, process (new UpcaseO, s); Apply, process (new DowncaseO, s); Apply, process (new SplitterO. s);
class Upcase extends StringProcessor {
public String process(Object input) { II Ковариантный возвращаемый тип return ((String)input) .toUpperCaseO;
class Downcase extends StringProcessor { public String process(Object input) {
return ((String)input).toLowerCase();
class Splitter extends StringProcessor {
public String process(Object input) {
return Arrays.toString(((String)input).split(" ")).
}
} /* Output
Используем Processor Upcase
IF SHE WEIGHS THE SAME AS A DUCK, SHE'S MADE OF WOOD Используем Processor Downcase if she weighs the same as a duck, she's made of wood Используем Processor Splitter
[If. she. weighs, the. same. as. a. duck., she's, made. of. wood] *///:-
Впрочем, довольно часто модификация тех классов, которые вы собираетесь использовать, невозможна. Например, в примере с электронными фильтрами библиотека была получена из внешнего источника. В таких ситуациях применяется паттерн «адаптер»: вы пишете код, который получает имеющийся интерфейс, и создаете тот интерфейс, который вам нужен:
//: interfaces/interfaceprocessor/FilterProcessor java package interfaces interfaceprocessor, import interfaces.filters.*;
class FilterAdapter implements Processor { Filter filter.
public FilterAdapter(Filter filter) { this.filter = filter.
}
public String nameO { return filter.nameO; } public Waveform process(Object input) {
return filter.process((Waveform)input).
}
}
public class FilterProcessor {
public static void main(String[] args) { Waveform w = new Waveform(); -