인터페이스는 객체의 동작을 정의하는 데 사용됩니다. 이것은 모든 인터페이스의 메소드가 노출 되었음을 의미 합니다 . 기본 메소드를 사용할 때 정의 된 메소드의 표준 구현을 제공하여 클래스 경계에서 코드 재사용을 제공 할 수 있습니다.
어떤 경우에는 기능이 필요하지만 (아마도 다른 기본 메소드 에서 코드를 재사용하기 위해 ) 클래스 / 객체의 네임 스페이스를 오염시키기 때문에 노출되어서는 안됩니다. 곳입니다 개인 기본 방법이 편리. 개인 기본 메소드의 예로는 팩토리, 유효성 검증 또는 기본 상태 처리가 있습니다.
package com.company;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Main {
public static void main(final String[] args) {
var messages =
List.of(
MessageQueue.newSubject("Message 1"),
MessageQueue.newTopic("Message 2"),
MessageQueue.newTopic("Message 3"));
final MessageQueueAdapter1 queue1 = () -> messages;
inspectQueue(queue1);
final MessageQueueAdapter2 queue2 = () -> messages;
inspectQueue(queue2);
}
private static void inspectQueue(final MessageQueue queue) {
final List<Message> messagesWithSubject = queue.getMessagesWithSubject();
assert messagesWithSubject.size() == 1 : "expected one message with 'Subject'";
final List<Message> messagesWithTopic = queue.getMessagesWithTopic();
assert messagesWithTopic.size() == 2 : "expected two message with 'Topic'";
assert !queue.getMessages().isEmpty() && 3 == queue.getMessages().size()
: "expected three messages in total";
}
@FunctionalInterface
interface Message {
private static boolean isPrefixedBy(final String message, final String prefix) {
return message != null && !message.isEmpty() && message.startsWith(prefix);
}
default boolean hasSubject() {
return isPrefixedBy(this.getMessage(), MessageQueue.PREFIX_SUBJECT);
}
default boolean hasTopic() {
return isPrefixedBy(this.getMessage(), MessageQueue.PREFIX_TOPIC);
}
String getMessage();
}
interface MessageQueue {
String PREFIX_SUBJECT = "Subject: ";
String PREFIX_TOPIC = "Topic: ";
private static Message newMessage(final String message) {
return () -> message;
}
static Message newSubject(final String message) {
return newMessage(PREFIX_SUBJECT + message);
}
static Message newTopic(final String message) {
return newMessage(PREFIX_TOPIC + message);
}
List<Message> getMessages();
List<Message> getMessagesWithSubject();
List<Message> getMessagesWithTopic();
}
@FunctionalInterface
interface MessageQueueAdapter1 extends MessageQueue {
private static List<Message> filterBy(
final List<Message> messages, final Predicate<Message> predicate) {
return messages.stream().filter(predicate).collect(Collectors.toList());
}
/** {@inheritDoc} */
@Override
default List<Message> getMessagesWithSubject() {
return filterBy(this.getMessages(), Message::hasSubject);
}
/** {@inheritDoc} */
@Override
default List<Message> getMessagesWithTopic() {
return filterBy(this.getMessages(), Message::hasTopic);
}
}
@FunctionalInterface
interface MessageQueueAdapter2 extends MessageQueue {
private List<Message> filterBy(final Predicate<Message> predicate) {
return this.getMessages().stream().filter(predicate).collect(Collectors.toList());
}
/** {@inheritDoc} */
@Override
default List<Message> getMessagesWithSubject() {
return filterBy(Message::hasSubject);
}
/** {@inheritDoc} */
@Override
default List<Message> getMessagesWithTopic() {
return filterBy(Message::hasTopic);
}
}
}