MultiParadigm Design in Java - PowerPoint PPT Presentation

1 / 39
About This Presentation
Title:

MultiParadigm Design in Java

Description:

Dynamic proxy. Create an implementation of one or more interfaces on the fly ... Subclasses are anonymous (optional) Template Method design pattern (GoF) We ... – PowerPoint PPT presentation

Number of Views:20
Avg rating:3.0/5.0
Slides: 40
Provided by: larsbry
Category:

less

Transcript and Presenter's Notes

Title: MultiParadigm Design in Java


1
Multi-Paradigm Design in Java
  • Frode Standal,
  • Chief Consultant
  • frode.standal_at_kantega.no
  • 47 92418571
  • www.kantega.no

2
Introduction
  • Java offers many programming paradigms
  • Object-Oriented Programming
  • Meta-Programming
  • Generic Programming (JDK 1.5)
  • Aspect-Oriented Programming
  • Avoid the Hammer-and-nail syndrome
  • Combine the different paradigms
  • Using Multi-Paradigm Design Principles
  • Examples from application development in the
    context of J2EE and EJB

3
Roadmap
  • Paradigms
  • Design Principles
  • Multi-Paradigm Design

4
Paradigms
  • Object-Oriented Programming
  • Meta-Programming
  • Generic Programming
  • Aspect-Oriented Programming

5
Object-Oriented Programming
  • Interface Inheritance
  • For subtyping (supporting polymorphism and
    dynamic binding)
  • Implementation Inheritance
  • For code reuse
  • Often combined
  • Known uses
  • Everywhere

6
Meta-Programming
  • An object usually represents a part of the
    application domain (e.g. Order, Customer) or the
    solution domain (e.g. Cache, AuthenticationFilter)
  • A meta-object represents a part of the program
    (e.g. Class, Method)

7
Meta-Programming Continued
  • Basic reflection
  • Get info on an objects methods (with arguments
    and return types) represented as an object
    (meta-object)
  • Invoke a method using the method meta-object
  • Dynamic proxy
  • Create an implementation of one or more
    interfaces on the fly
  • The implementation delegates to an invocation
    handler providing meta-information
  • Some known uses
  • In web application frameworks (e.g. Struts and
    WebWork) for mapping HTTP request parameters to
    java beans and for accessing java beans from JSP
    tags
  • In the Spring framework for mapping configuration
    files to java beans

8
Generic Programming
  • Generic class
  • A class that serves as a template for a group of
    classes which share implementation
  • Is parameterized by one or more other classes
  • Example public class Buffer ltTgt ...
  • We must provide actual parameters when creating
    an instance of the class BufferltMessagegt buffer
    new BufferltMessagegt()
  • Generic method
  • A method that serves as a template for a group of
    methods which share implementation
  • Is parameterized by one or more other classes
  • Some known uses
  • The Collections API

9
Aspect-Oriented Programming
  • An aspect is a modularization of the
    implementation of a requirement which affects
    many classes/methods/modules (often a
    non-functional requirement)
  • Advice
  • Piece of code to be executed before/after/around
    a set of points of execution (join points) of a
    program
  • A set of join points are specified using a
    wildcard syntax
  • Method introduction
  • Adding methods or fields to existing
    classes/interfaces
  • Mixin inheritance
  • Modifying the inheritance hierarchy of existing
    classes/interfaces

10
Aspect-Oriented Programming Continued
  • Alternative AOP technolgies
  • AspectJ, JBoss AOP, Spring AOP, AspectWerkz,
    Nanning
  • Aspects are weaved into the program
  • AspectJ uses a special compiler to do this
  • Some known uses of AOP
  • JBoss 4 (transactions, security, caching, etc)
  • Spring (transactions, security, etc)
  • Logging

11
Design Principles
  • Modularity
  • Grouping logically related code
  • Minimizing the dependencies among modules
  • The Open-Closed Principle
  • It should be possible to extend the behaviour of
    an module without having to modify existing code
  • Refactor common code
  • Avoid code duplication

12
Refactoring
  • Choose refactoring strategy depending on the
    commonalities and variabilities in your code
  • Interface Inheritance
  • Commonality Types and method signatures
  • Variability Algorithm implementation
  • Implementation Inheritance
  • Commonality Behaviour and data structure
  • Variability Behaviour and data structure

13
Refactoring
  • Generic classes and methods
  • Commonality Behaviour and data structure
  • Variability Detailed type(s)
  • Basic reflection
  • Commonality Read/modify properties of an object
  • Variability The types, names, and number of
    properties
  • AOP Advice
  • Commonality Code to be executed
    before/after/around the execution of methods
  • Variability The methods/classes/packages where
    the common code is needed

14
Multi-Paradigm Design
  • Requirements
  • Architectural Context
  • Iterative Analysis and Solution Design

15
Requirements
  • Use-Case View Orders
  • Basic Flow
  • Actor Customer
  • The user selects the View Orders operation
  • The system reads all the customers orders from
    the database, and displays the order information
    for each order
  • The user selects one of the displayed orders
  • The system reads all the order details (line
    items) from the database and displays them

16
Requirements Continued
  • Alternative flow
  • Actor Administrator
  • The administrator selects a customer
  • Same as basic flow, steps 1-4

17
Architectural Context
  • J2EE
  • EJB (Stateless session beans)
  • JDBC
  • DAO (Data Access Object)
  • DTO (Data Transfer Object)

18
Iteration 0 - Solution Design
  • Stateless session bean OrderService
  • Collection getOrders(String customer)
  • Collection getOrderDetails(Integer orderId)
  • The methods return collection of Order and
    OrderDetail respectively (DTOs)
  • The methods delegate to DAO which encapsulates
    database access

19
public Collection getOrders(String customer)
Connection conn null PreparedStatement ps
null ResultSet rs null try conn
dataSource.getConnection() String stmt
"select id, customer, order_date from
orders where customer ?" ps
conn.prepareStatement(stmt) ps.setString(1,
customer) rs ps.executeQuery()
Collection result new ArrayList() while
(rs.next()) Order o new Order()
o.setId(new Integer(rs.getInt("id")))
o.setCustomer(rs.getString("customer"))
o.setOrderDate(rs.getTimestamp("order_date"))
result.add(o) return result
catch (SQLException e) log.error("", e)
throw new DBException(e) finally
try if (rs ! null) rs.close()
catch (SQLException e) try if (ps
! null) ps.close() catch
(SQLException e) try if (conn !
null) conn.close() catch (SQLException
e)
public Collection getOrderDetails(Integer
orderId) Connection conn null
PreparedStatement ps null ResultSet rs
null try conn dataSource.getConnection
() String stmt "select id, name, order_id,
unit_price, count from order_details where
order_id ?" ps conn.prepareStatement(stmt
) ps.setObject(1, orderId) rs
ps.executeQuery() Collection result new
ArrayList() while (rs.next())
OrderDetail o new OrderDetail()
o.setId(new Integer(rs.getInt("id")))
o.setName(rs.getString("name"))
o.setOrderId(new Integer(rs.getInt("order_id")))
o.setUnitPrice(rs.getFloat("unit_price"))
o.setCount(rs.getInt("count"))
result.add(o) return result
catch (SQLException e) log.error("", e)
throw new DBException(e) finally
try if (rs ! null) rs.close()
catch (SQLException e) try if (ps
! null) ps.close() catch
(SQLException e) try if (conn !
null) conn.close() catch (SQLException
e)
20
Iteration 1 - Analysis
  • Commonalities Overall algorithm
  • Get database connection
  • Create SQL statement
  • Execute statement
  • Process result set
  • Close connection
  • Variabilities
  • Query
  • Result set
  • Type of DTO

21
Iteration 1 - Solution Design
  • Refactor using object orientation
  • Capture overall algorithm in a base class
    (DBQuery)
  • Implement query, result set handling and DTO
    initialization in subclasses

22
public abstract class DBQuery public
Collection select(String query, Object arg
Connection conn null PreparedStatement ps
null ResultSet rs null try
conn dataSource.getConnection() ps
conn.prepareStatement(query)
fillStatement(ps, args) rs
ps.executeQuery() Collection result new
ArrayList() while (rs.next())
Object o processRow(rs)
result.add(o) return result
catch (SQLException e)
log.error("", e) throw new
DBException(e) finally try
if (rs ! null) rs.close()
catch (SQLException e) try if
(ps ! null) ps.close() catch
(SQLException e) try if (conn
! null) conn.close() catch
(SQLException e) protected
abstract Object processRow(ResultSet rs)
throws SQLException
public Collection getOrders(String customer)
DBQuery query new DBQuery(dataSource)
protected Object processRow(ResultSet rs)
throws SQLException Order o new
Order() o.setId(new Integer(rs.getInt("id")
)) o.setCustomer(rs.getString("customer"))
o.setOrderDate(rs.getTimestamp("order_date"
)) return o String stmt
"select id, customer, order_date from orders
where customer ?" return query.select(stmt,
new Object customer ) public Collection
getOrderDetails(Integer orderId) DBQuery
query new DBQuery(dataSource) protected
Object processRow(ResultSet rs) throws
SQLException OrderDetail o new
OrderDetail() o.setId(new
Integer(rs.getInt("id")))
o.setName(rs.getString("name"))
o.setOrderId(new Integer(rs.getInt("order_id")))
o.setUnitPrice(rs.getFloat("unit_price"))
o.setCount(rs.getInt("count")) return
o String stmt "select id, name,
order_id, unit_price, count from order_details
where order_id ?" return query.select(stmt,
new Object orderId )
23
Iteration 1 - Solution Design Continued
  • Base class is abstract
  • Subclasses are anonymous (optional)
  • Template Method design pattern (GoF)
  • We have achieved
  • Less code to write
  • Enforced cleanup code (avoiding potential
    resource leak)
  • Only one place to maintain cleanup code
  • Avoided the cutpaste programming antipattern

24
Iteration 2 - Analysis
public Collection getOrders(String customer)
DBQuery query new DBQuery(dataSource)
protected Object processRow(ResultSet rs)
throws SQLException Order o new
Order() o.setId(new Integer(rs.getInt("id")
)) o.setCustomer(rs.getString("customer"))
o.setOrderDate(rs.getTimestamp("order_date"
)) return o String stmt
"select id, customer, order_date from orders
where customer ?" return query.select(stmt,
new Object customer )
public Collection getOrderDetails(Integer
orderId) DBQuery query new
DBQuery(dataSource) protected Object
processRow(ResultSet rs) throws
SQLException OrderDetail o new
OrderDetail() o.setId(new
Integer(rs.getInt("id")))
o.setName(rs.getString("name"))
o.setOrderId(new Integer(rs.getInt("order_id")))
o.setUnitPrice(rs.getFloat("unit_price"))
o.setCount(rs.getInt("count")) return
o String stmt "select id, name,
order_id, unit_price, count from order_details
where order_id ?" return query.select(stmt,
new Object orderId )
25
Iteration 2 - Analysis Continued
  • Commonalities
  • Create DTO
  • For each column get value from result set and
    call setter in DTO
  • Variabilities
  • Different type of DTO
  • Column values have different names and types
  • DTO properties have different names and types
  • Variable number of columns/properties

26
Iteration 2 - Solution Design
  • Refactor using meta-programming in DBQuery to
  • Create DTO instances
  • Find names of columns from result set
  • Find names of setters in DTO
  • Call setters with values extracted from result
    set
  • Assume a naming convention between column name
    and property name (e.g. order_id and orderId)
  • No need for subclasses of DBQuery anymore

27
public class DBQuery public Collection
select(Class cls,
String query,
Object args) Connection conn null
PreparedStatement ps null ResultSet rs
null try conn dataSource.getConnec
tion() ps conn.prepareStatement(query)
fillStatement(ps, args) rs
ps.executeQuery() Collection result
buildResult(cls, rs) return result
catch (SQLException e) log.error("",
e) throw new DBException(e)
finally try if (rs ! null)
rs.close() catch (SQLException e)
try if (ps ! null)
ps.close() catch (SQLException e)
try if (conn ! null)
conn.close() catch (SQLException
e)
protected Collection buildResult(Class cls,
ResultSet rs) throws SQLException
ResultSetMetaData md rs.getMetaData() try
ArrayList list new ArrayList() while
(rs.next()) Object o cls.newInstance()
for (int i 0 i lt md.getColumnCount()
i) String columnName
md.getColumnName(i1) String
propertyName toPropertyName(columnName)
PropertyDescriptor pd new
PropertyDescriptor(propertyName, o.getClass())
Method method pd.getWriteMethod()
Class propertyClass pd.getPropertyType()
Object arg null arg getValue(rs,
i1, propertyClass) Object args
arg method.invoke(o, args)
list.add(o) return list
catch (Exception e) throw new
DBException(e)
28
Iteration 2 - Solution Design Continued
public Collection getOrders(String customer)
String stmt "select id, customer,
order_date from orders where customer ?"
return query.select(Order.class, stmt, new
Object customer ) public Collection
getOrderDetails(Integer orderId) String
stmt "select id, name, order_id,
unit_price, count from order_details where
order_id ?" return query.select(OrderDetail.c
lass, stmt, new Object orderId )
29
Iteration 3 - Analysis
public Collection getOrders(String customer)
public Collection getOrderDetails(Integer
orderId)
  • Both methods return a Collection, but element
    type is not specified in the method signature,
    needing documentation to tell the client
    programmer what to expect
  • No compile-time type checking

30
Iteration 3 - Solution Design
  • Use generic programming
  • Provides self-documenting code and compile-time
    type checking on client
  • What about server side?

public CollectionltOrdergt getOrders(String
customer) public CollectionltOrderDetailgt
getOrderDetails(Integer orderId)
31
Iteration 3 - Solution Design Continued
  • Make DBQuery.select a generic method
  • java.lang.Class is generic
  • The type of Order.class is ClassltOrdergt
  • The type of Order.class.newInstance() is Order

public ltEgt CollectionltEgt select(ClassltEgt cls,
String query,
Object args)
32
public class DBQuery public ltEgt
CollectionltEgt select(ClassltEgt cls,
String query,
Object args) Connection conn
null PreparedStatement ps null
ResultSet rs null try conn
dataSource.getConnection() ps
conn.prepareStatement(query)
fillStatement(ps, args) rs
ps.executeQuery() CollectionltEgt result
buildResult(cls, rs) return result
catch (SQLException e) log.error("",
e) throw new DBException(e)
finally try if (rs ! null)
rs.close() catch (SQLException e)
try if (ps ! null)
ps.close() catch (SQLException e)
try if (conn ! null)
conn.close() catch (SQLException
e)
protected ltEgt CollectionltEgt buildResult(ClassltEgt
cls,
ResultSet rs) throws SQLException
ResultSetMetaData md rs.getMetaData() try
ArrayListltEgt list new ArrayListltEgt()
while (rs.next()) E o
cls.newInstance() for (int i 0 i lt
md.getColumnCount() i) String
columnName md.getColumnName(i1)
String propertyName toPropertyName(columnName)
PropertyDescriptor pd new
PropertyDescriptor(propertyName, o.getClass())
Method method pd.getWriteMethod()
Class propertyClass pd.getPropertyType()
Object arg null arg getValue(rs,
i1, propertyClass) Object args
arg method.invoke(o, args)
list.add(o) return list
catch (Exception e) throw new
DBException(e)
33
Iteration 3 - Solution Design Continued
CollectionltOrdergt getOrders(String customer)
String stmt "select id, customer,
order_date from orders where customer ?"
return query.select(Order.class, stmt, new
Object customer ) CollectionltOrderDe
tailgt getOrderDetails(Integer orderId)
String stmt "select id, name, order_id,
unit_price, count from order_details where
order_id ?" return query.select(OrderDetail.c
lass, stmt, new Object orderId )
  • Now we have compile-time type checking on server
    as well

34
New requirements Access control
  • A customer may only see own orders and order
    details
  • An administrator may se all customers orders and
    order details

35
Iteration 4 Analysis
  • We do not want mix access control logic with
    business logic/persistence logic (the modularity
    principle)
  • We do not want to change existing code (the
    open-closed principle)
  • EJB does not support declarative data-based
    access control (only pure role-based)
  • No portable way to intercept calls to EJB using
    the proxy-, decorator- or interceptor design
    patterns

36
Iteration 4 Solution Design
  • Use aspect-oriented programming
  • Create an aspect which handles the access control
    requirement
  • Define before-advice for the methods in
    OrderService

37
public aspect OrderAccessControl
before(OrderServiceEJB bean, String customer)
execution( OrderServiceEJB.getOrders(String))
this(bean) args(customer)
checkAccess(bean.getSessionContext(),
customer) before(OrderServiceEJB bean,
Integer orderId) execution(
OrderServiceEJB.getOrderDetails(Integer))
this(bean) args(orderId) String
customer bean.getOrderDAO().getCustomerByOrder(o
rderId) checkAccess(bean.getSessionContext(),
customer) public void
checkAccess(SessionContext ctx, String customer)
if (!ctx.isCallerInRole("administrator"))
String caller ctx.getCallerPrincipal().g
etName() if (!caller.equals(customer))
throw new java.security.AccessControlException
("Access denied. " caller " tried
to access data belonging to " customer)

38
Summary
  • We have combined the programming paradigms to
    achieve a better design
  • Multi-paradigm design supplements
  • Design patterns
  • Java coding idioms
  • Frameworks

39
Bibliography
  • Multi-Paradigm Design for C (J. Coplien)
  • Design Patterns (E. Gamma et al.)
  • Java Reflection in Action (I. and N. Forman)
  • The Art of the Metaobject Protocol (G. Kiczales
    et al.)
  • Generics in the Java Programming Language (G.
    Bracha)
  • AspectJ in Action (R. Laddad)
Write a Comment
User Comments (0)
About PowerShow.com