decouplingcs decoupling case studyriad.usk.pk.edu.pl/~pzabawa/en/files/ei/decouplingcs.pdf · 1...

12
1 Piotr Zabawa, PhD. Eng. Krakow, 10 th of December, 2011 Software Engineering Section Faculty of Physics, Mathematics and Computer Science Cracow University of Technology e-mail: [email protected] www: http://www.pk.edu.pl/~pzabawa/en www: http://www.pk.edu.pl/~pzabawa/en/business.html DecouplingCS Decoupling Case Study This case study explains step-by-step the concept of decoupling. It recognizes problems characteristic for each implementation of decoupling and moves forward making the decoupling better. This case study is composed of several projects: 1. JavaSEDecouplingTCS - investigation of decoupling barriers in case of Java Standard Edition 2. AspectJDecouplingTCS - decoupling based on application of AOP 3. SeamDecouplingTCS - possible solutions of decoupling problem offered by application of Seam Framework 4. SpringDecouplingTCS - possible solutions of decoupling problem offered by application of Spring Framework 5. *DecouplingTCS_soa - application of SOA for each framework for technology decoupling All projects are implemented and ready for execution and are published in the form of *.zip files. Each zip file may consist of many projects. The case-study scenario is presented below.

Upload: others

Post on 14-Jun-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

1

Piotr Zabawa, PhD. Eng. Krakow, 10th

of December, 2011

Software Engineering Section

Faculty of Physics, Mathematics and Computer Science

Cracow University of Technology

e-mail: [email protected]

www: http://www.pk.edu.pl/~pzabawa/en

www: http://www.pk.edu.pl/~pzabawa/en/business.html

DecouplingCS

Decoupling Case Study

This case study explains step-by-step the concept of decoupling. It recognizes problems characteristic

for each implementation of decoupling and moves forward making the decoupling better. This case

study is composed of several projects:

1. JavaSEDecouplingTCS - investigation of decoupling barriers in case of Java Standard Edition

2. AspectJDecouplingTCS - decoupling based on application of AOP

3. SeamDecouplingTCS - possible solutions of decoupling problem offered by application of

Seam Framework

4. SpringDecouplingTCS - possible solutions of decoupling problem offered by application of

Spring Framework

5. *DecouplingTCS_soa - application of SOA for each framework for technology decoupling

All projects are implemented and ready for execution and are published in the form of *.zip files.

Each zip file may consist of many projects.

The case-study scenario is presented below.

Page 2: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

2

SOA

JavaEE

AspectJ

SpringSeam

JavaSE

JavaSEDecouplingTCS_01_simple

JavaSEDecouplingTCS_02_cmd

JavaSEDecouplingTCS_03_service

JavaSEDecouplingTCS_04_jinterface

JavaSEDecouplingTCS_05_jfactory

SpringDecouplingTCS_01_factory

SpringDecouplingTCS_02_diprops

SpringDecouplingTCS_03_dixml

SpringDecouplingTCS_04_dixmlctorarg

SpringDecouplingTCS_06_ws

SpringDecouplingTCS_07_soa

SpringDecouplingTCS_05_annot

SeamDecouplingTCS_01_factory

SeamDecouplingTCS_02_diprops

SeamDecouplingTCS_03_dixml

SeamDecouplingTCS_04_dixmlctorarg

SeamDecouplingTCS_06_ws

SeamDecouplingTCS_07_soa

SeamDecouplingTCS_05_annot

AspectJDecouplingTCS_04a_simple

AspectJDecouplingTCS_05_factory

The idea of the whole case-study is to find a good solution of decoupling service provider from

service consumer. That means that any changes introduced to one of them must not involve any

changes in the other.

Page 3: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

3

JavaSEDecouplingTCS

JavaSEDecouplingTCS_01_simple

Characteristics:

package pl.edu.pk.ip.decoupling.simple;

public class HelloWorldSimple {

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

Disadvantages:

Any changes introduced into service provider (a message to be printed) influence the whole

source code and result in recompilation of the whole source code. No distinction between

service provider and service consumer.

Opportunities:

Introduction of flexibility in message changing.

JavaSEDecouplingTCS_02_cmd

Characteristics:

package pl.edu.pk.ip.decoupling.cmd;

public class HelloWorldCmd {

public static void main(String[] args) {

if (args.length > 0) {

System.out.println(args[0]);

} else {

System.out.println("Hello World!");

}

}

}

Improvements:

Message can be changed runtime without the need of source code recompilation.

Disadvantages:

Hardcoded way of printing (println), no way of different rendering or to printing to different

target without recompilation. Printing is directly associated to obtaining the message. Still no

distinction between service provider and service consumer.

Opportunities:

Separation of obtaining message logic (service provider) from rendering message logic

(service consumer). This way we can change any logic without affecting the other.

JavaSEDecouplingTCS_03_service

HelloWorldSimple.java

HelloWorldCmd.java

Page 4: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

4

Characteristics:

package pl.edu.pk.ip.decoupling.service;

public class HelloWorldServiceProvider {

public String getMessage() {

return "Hello World!";

}

}

package pl.edu.pk.ip.decoupling.service;

public class HelloWorldServiceConsumer {

private HelloWorldServiceProvider messageProvider = null;

public void setMessageProvider(HelloWorldServiceProvider provider) {

this.messageProvider = provider;

}

public void render() {

String message = messageProvider.getMessage();

System.out.println(message);

}

}

package pl.edu.pk.ip.decoupling.service;

public class HelloWorldBusinessProcess {

public static void main(String[] args) {

HelloWorldServiceConsumer mr = new HelloWorldServiceConsumer();

HelloWorldServiceProvider mp = new HelloWorldServiceProvider();

mr.setMessageProvider(mp);

mr.render();

}

}

Improvements:

Separation of service provider and service consumer logic was achieved. Introduction of

changes into one of them does not affect the other.

Disadvantages:

A particular message provider is hardcoded into message consumer. So, switching to other

service provider without changing in the source code of service consumer is limited.

Opportunities:

Introduction of services will eliminate the problem of switching to other service provider.

JavaSEDecouplingTCS_04_jinterface

Characteristics:

package pl.edu.pk.ip.decoupling.jinterface;

public interface ServiceProviderInterface {

public String getMessage();

}

HelloWorldServiceProvider.java

HelloWorldServiceConsumer.java

HelloWorldBusinessProcess.java

ServiceProviderInterface.java

Page 5: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

5

package pl.edu.pk.ip.decoupling.jinterface;

public class ServiceProviderImplementation implements ServiceProviderInterface {

public String getMessage() {

return "Hello World!";

}

}

package pl.edu.pk.ip.decoupling.jinterface;

public interface ServiceConsumerInterface {

public void render();

public void setMessageProvider(ServiceProviderInterface provider);

public ServiceProviderInterface getMessageProvider();

}

package pl.edu.pk.ip.decoupling.jinterface;

public class ServiceConsumerImplementation implements ServiceConsumerInterface {

private ServiceProviderInterface messageProvider = null;

public void render() {

if (messageProvider == null) {

throw new RuntimeException(

"You must set the property messageProvider of class:"

+ ServiceConsumerInterface.class.getName());

}

System.out.println(messageProvider.getMessage());

}

public void setMessageProvider(ServiceProviderInterface provider) {

this.messageProvider = provider;

}

public ServiceProviderInterface getMessageProvider() {

return this.messageProvider;

}

}

package pl.edu.pk.ip.decoupling.jinterface;

public class BusinessProcess {

public static void main(String[] args) {

ServiceConsumerInterface mr = new ServiceConsumerImplementation();

ServiceProviderInterface mp = new ServiceProviderImplementation();

mr.setMessageProvider(mp);

mr.render();

}

}

Improvements:

Message provider may change without impact to message consumer.

Disadvantages:

Both provider and consumer may change independently one to another. But these changes

have strong impact onto business logic (the launcher).

Opportunities:

ServiceProviderImplementation.java

ServiceConsumerInterface.java

ServiceConsumerImplementation.java

BusinessProcess.java

Page 6: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

6

The responsibility of creation of objects of the right classes may be delegated to the factory

design pattern.

JavaSEDecouplingTCS_05_jfactory

Characteristics:

package pl.edu.pk.ip.decoupling.jfactory;

import java.io.FileInputStream;

import java.util.Properties;

public class DecouplingFactory {

private static DecouplingFactory instance = null;

private Properties props = null;

private ServiceConsumerInterface renderer = null;

private ServiceProviderInterface provider = null;

private DecouplingFactory() {

props = new Properties();

try {

props.load(new FileInputStream("factory.properties"));

String rendererClass = props.getProperty("consumer.class");

String providerClass = props.getProperty("provider.class");

renderer = (ServiceConsumerInterface)

Class.forName(rendererClass).newInstance();

provider = (ServiceProviderInterface)

Class.forName(providerClass).newInstance();

} catch (Exception ex) {

ex.printStackTrace();

}

}

static {

instance = new DecouplingFactory();

}

public static DecouplingFactory getInstance() {

return instance;

}

public ServiceConsumerInterface getMessageRenderer() {

return renderer;

}

public ServiceProviderInterface getMessageProvider() {

return provider;

}

}

consumer.class=pl.edu.pk.ip.decoupling.jfactory.ServiceConsumerImplementation

provider.class=pl.edu.pk.ip.decoupling.jfactory.ServiceProviderImplementation

package pl.edu.pk.ip.decoupling.jfactory;

public class BusinessProcess {

public static void main(String[] args) {

ServiceConsumerInterface mr =

DecouplingFactory.getInstance().getMessageRenderer();

ServiceProviderInterface mp =

DecouplingFactory.getInstance().getMessageProvider();

mr.setMessageProvider(mp);

mr.render();

}

}

DecouplingFactory.java

factory.properties

BusinessProcess.java

Page 7: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

7

Improvements:

No any change must be done in source code to change service provider. It is enough to

change items in property file.

Disadvantages:

In order to achieve this level of decoupling the glue code is needed. It consists of the factory

implementation as well as association of message provider into message consumer. This is

called wiring.

Opportunities:

Wiring could be handled by a framework. In fact it is supported by both Seam and Spring

Java EE frameworks by their built-in factories and mechanism for associating objects.

AspectJDecouplingTCS

SeamDecouplingTCS

SpringDecouplingTCS

SpringDecouplingTCS_01_factory

Characteristics:

package pl.edu.pk.ip.decoupling.springfactory;

import java.io.FileInputStream;

import java.util.Properties;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;

import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;

public class BusinessProcess {

public static void main(String[] args) throws Exception {

BeanFactory factory = getBeanFactory();

ServiceConsumerInterface mr = (ServiceConsumerInterface)

factory.getBean("consumer");

ServiceProviderInterface mp = (ServiceProviderInterface)

factory.getBean("provider");

mr.setMessageProvider(mp);

mr.render();

}

private static BeanFactory getBeanFactory() throws Exception {

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

PropertiesBeanDefinitionReader rdr = new

PropertiesBeanDefinitionReader(factory);

Properties props = new Properties();

props.load(new FileInputStream("factory.properties"));

rdr.registerBeanDefinitions(props);

return factory;

}

}

BusinessProcess.java

Page 8: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

8

consumer.(class)=pl.edu.pk.ip.decoupling.springfactory.ServiceConsumerImplementation

provider.(class)=pl.edu.pk.ip.decoupling.springfactory.ServiceProviderImplementation

Improvements:

User implemented glue code was limited due to the usage of Spring built-in low-level internal

factory - the Spring framework implementation of factory method design pattern.

Disadvantages:

There is still a glue code in business process which is responsible for creation of service

provider, the service of which is not directly used from business process. Creation of this

object is necessary for passing it to the service consumer in order to configure the last one.

Opportunities:

The wiring of service provider into service consumer can be eliminated from the source code

to limit the amount of work business process must perform.

SpringDecouplingTCS_02_diprops

Characteristics:

package pl.edu.pk.ip.decoupling.springdiprops;

import java.io.FileInputStream;

import java.util.Properties;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;

import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;

public class BusinessProcess {

public static void main(String[] args) throws Exception {

BeanFactory factory = getBeanFactory();

ServiceConsumerInterface mr = (ServiceConsumerInterface)

factory.getBean("consumer");

mr.render();

}

private static BeanFactory getBeanFactory() throws Exception {

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

PropertiesBeanDefinitionReader rdr = new

PropertiesBeanDefinitionReader(factory);

Properties props = new Properties();

props.load(new FileInputStream("factory.properties"));

rdr.registerBeanDefinitions(props);

return factory;

}

}

consumer.(class)=pl.edu.pk.ip.decoupling.springdiprops.ServiceConsumerImplementation

consumer.messageProvider(ref)=provider

provider.(class)=pl.edu.pk.ip.decoupling.springdiprops.ServiceProviderImplementation

Improvements:

factory.properties

factory.properties

BusinessProcess.java

Page 9: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

9

Source code in business logic was limited to the one really necessary for executing service

consumer method. This way the whole glue code was eliminated.

Disadvantages:

The usage of low-level Spring factory is inconvenient - a lot of source code for factory

creation and for making use of java-like properties file.

Opportunities:

There are also other factories available in Spring that work on more genera level. However

they need an XML file in place of properties file.

SpringDecouplingTCS_03_dixml

Characteristics:

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-

beans.dtd">

<beans>

<bean id="consumer"

class="pl.edu.pk.ip.decoupling.springdixml.ServiceConsumerImplementation">

<property name="messageProvider">

<ref local="provider"/>

</property>

</bean>

<bean id="provider"

class="pl.edu.pk.ip.decoupling.springdixml.ServiceProviderImplementation"/>

</beans>

package pl.edu.pk.ip.decoupling.springdixml;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BusinessProcess {

public static void main(String[] args) throws Exception {

BeanFactory factory = getBeanFactory();

ServiceConsumerInterface mr = (ServiceConsumerInterface)

factory.getBean("consumer");

mr.render();

}

private static BeanFactory getBeanFactory() throws Exception {

BeanFactory factory = new ClassPathXmlApplicationContext("/beans.xml");

return factory;

}

}

Improvements:

Due to application of dependency injection supported by Spring framework the source code

is free from any glue code.

Disadvantages:

Message is still hardcoded into message provider.

beans.xml

BusinessProcess.java

Page 10: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

10

Opportunities:

Message can be passed to message provider as a constructor argument.

SpringDecouplingTCS_04_dixmlctorarg

Characteristics:

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-

beans.dtd">

<beans>

<bean id="consumer"

class="pl.edu.pk.ip.decoupling.springdixmlctorarg.ServiceConsumerImplementation">

<property name="messageProvider">

<ref local="provider"/>

</property>

</bean>

<bean id="provider"

class="pl.edu.pk.ip.decoupling.springdixmlctorarg.ServiceProviderImplementation">

<constructor-arg>

<value>This is an XML bean ctor configurable message!</value>

</constructor-arg>

</bean>

</beans>

package pl.edu.pk.ip.decoupling.springdixmlctorarg;

public class ServiceProviderImplementation implements ServiceProviderInterface {

private String message;

public ServiceProviderImplementation(String message) {

this.message = message;

}

public String getMessage() {

return message;

}

}

Improvements:

Configuration file is responsible for passing fixed data into objects of a particular class during

object construction. This way an initialization can be performed without any impact to the

source code.

Disadvantages:

Both service provider and service consumer are implemented in the same technology

(JavaSE+Spring). None of them can be switched to another technology nor can be reused

from different technology.

Opportunities:

Web Services may be applied in order to decouple technologies as well.

beans.xml

ServiceProviderImplementation.java

ml

Page 11: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

11

SpringDecouplingTCS_05_annotation

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html

Characteristics:

Improvements:

Disadvantages:

Opportunities:

WSDecouplingTCS

Web Services can be implemented in many ways. However the most important goal of this analysis is

to show how WS can decouple technologies used in both sides: service provider and service

consumer.

WSDecouplingTCS_06_jaxwsapachecxf

Characteristics:

Improvements:

Disadvantages:

Opportunities:

WSDecouplingTCS_07_soa

Characteristics:

Improvements:

Disadvantages:

Opportunities:

WTPDecouplingTCS ?

Page 12: DecouplingCS Decoupling Case Studyriad.usk.pk.edu.pl/~pzabawa/en/files/EI/DecouplingCS.pdf · 1 Piotr Zabawa, PhD. Eng. Krakow, 10th of December, 2011 Software Engineering Section

12