Java/Spring/Decouple
Closed Coupled
<source lang="java">
File: Main.java import java.io.PrintStream; public class Main {
public static void main(String[] a) { MessageData source = new MessageData("Hello, world"); MessageReporter destination = new MessageReporter(); destination.write(System.out, source.getMessage()); }
} final class MessageData {
private final String message; public MessageData(String message) { this.message = message; } public String getMessage() { return message; }
} class MessageReporter {
public void write(PrintStream out, String message) { out.println(message); }
}
</source>
Decouple With Interface
<source lang="java">
File: Main.java
public class Main {
public static void main(String[] a) { MessageData source = new SimpleMessageData("Hello, world"); MessageReporter destination = new StdoutMessageReporter(); destination.write(source.getMessage()); }
} interface MessageReporter {
void write(String message);
} interface MessageData {
String getMessage();
} class StdoutMessageReporter implements MessageReporter {
public void write(String message) { System.out.println(message); }
} class SimpleMessageData implements MessageData {
private final String message; public SimpleMessageData() { this("Hello, world"); } public SimpleMessageData(String message) { this.message = message; } public String getMessage() { return this.message; }
}
</source>
Spring Prototype
<source lang="java">
File: Main.java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main {
public static void main(String[] z) { ApplicationContext context = new ClassPathXmlApplicationContext("context.xml", Main.class); SpringPrototypeClient client = (SpringPrototypeClient) context.getBean("prototypeClient"); client.run(); }
} class SpringPrototypeClient {
private Message message1; private Message message2; public void run() { System.out.println("Message1 " + this.message1.toString()); System.out.println("Message2 " + this.message2.toString()); System.out.println("Messages == " + (this.message1 == this.message2)); } public void setMessage1(Message message1) { this.message1 = message1; } public void setMessage2(Message message2) { this.message2 = message2; }
} abstract class Message {
public Message makeCopy() { try { return this.getClass().newInstance(); } catch (InstantiationException e) { return null; } catch (IllegalAccessException e) { return null; } }
} class EmailMessage extends Message {
@Override public String toString() { return "EmailMessage"; }
}
File: context.xml <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>
<bean id="prototypeClient" class="SpringPrototypeClient"> <property name="message1" ref="message"/> <property name="message2" ref="message"/> </bean> <bean id="message" class="EmailMessage" singleton="false"/>
</beans>
</source>
Spring Style Decouple
<source lang="java">
File: helloworld-context.properties source.(class)=SimpleMessageData destination.(class)=StdoutMessageReporter
File: Main.java import org.springframework.beans.factory.support.BeanDefinitionReader; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; public class Main {
public static void main(String[] a) { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(bf); reader.loadBeanDefinitions(new ClassPathResource("helloworld-context.properties")); MessageData source = (MessageData) bf.getBean("source"); MessageReporter destination = (MessageReporter) bf.getBean("destination"); destination.write(source.getMessage()); }
} interface MessageService {
void execute();
} class DefaultMessageService implements MessageService {
private MessageData source; private MessageReporter destination; public void execute() { this.destination.write(this.source.getMessage()); } public void setSource(MessageData source) { this.source = source; } public void setDestination(MessageReporter destination) { this.destination = destination; }
} interface MessageReporter {
void write(String message);
} interface MessageData {
String getMessage();
} class StdoutMessageReporter implements MessageReporter {
public void write(String message) { System.out.println(message); }
} class SimpleMessageData implements MessageData {
private final String message; public SimpleMessageData() { this("Hello, world"); } public SimpleMessageData(String message) { this.message = message; } public String getMessage() { return this.message; }
}
</source>