Designing Systems That Evolve Quickly and Cleanly - PowerPoint PPT Presentation

1 / 48
About This Presentation
Title:

Designing Systems That Evolve Quickly and Cleanly

Description:

Is the system in a state that allows you to easily add/modify a feature? ... Modern IDEs (most notably IntelliJ IDEA) have automated much of this. ... – PowerPoint PPT presentation

Number of Views:63
Avg rating:3.0/5.0
Slides: 49
Provided by: jimm211
Learn more at: http://www.gatorjug.org
Category:

less

Transcript and Presenter's Notes

Title: Designing Systems That Evolve Quickly and Cleanly


1
Designing Systems That Evolve Quickly and Cleanly
  • by Jim Moore

2
Evolving the System
  • Is the system in a state that allows you to
    easily add/modify a feature?
  • If no, refactor it to allow what you need.
  • Add/modify the feature.
  • Do this, and everything will be easy -)

3
Refactoring
  • Refactoring is the practice of changing the
    structure of code without changing what it does.
  • Modern IDEs (most notably IntelliJ IDEA) have
    automated much of this.
  • When a tool cant do a change in a verifiably
    correct way, its vital that you have tests to
    make sure you didnt just break something!

4
Overview
  • Defining the Problem
  • Code Rot
  • Coupling Cohesion
  • Technologies
  • Test Driven Development
  • Interfaces
  • Dependency Injection
  • Mixins
  • Package Management
  • Tools

5
  • Defining the Problem

6
What Is Code Rot?
  • Code Rot is where code goes progressively bad
    over time.
  • Once clean designs become a tangled mess. Any
    changes are increasingly error-prone.
  • Makes refactoring a challenge.

7
Five Signs of Code Rot
  • Rigidity
  • Fragility
  • Immobility
  • Obscurity
  • Dispensability

http//www.cincomsmalltalk.com/userblogs/buck/bl
ogView?entry3320476400
8
Code Rot Rigidity
  • A small change to the design requires
    wide-sweeping changes to the code.
  • Also known as the Local Change, Local Effect
    principle.

9
Code Rot Fragility
  • A small change in one spot causes many things to
    break.
  • The But I just made one little thing in an
    unrelated part of the system effect.

10
Code Rot Immobility
  • Code is difficult to reuse in contexts other than
    the original one.
  • Encourages a lot of reinventing the wheel.
  • Virtually impossible to test in isolation.

11
Code Rot Obscurity
  • The code is difficult to read and understand.
  • This is a major cause of maintenance bugs.
  • Leads to a lot of redundancy, because if you have
    no idea what something is really going to do, you
    are unlikely to reuse it.

12
Code Rot Dispensability
  • The code is redundant or not needed at all.
  • Is this class used any more? Maybe. Who knows,
    but I'm sure not going to touch it.

13
Coupling Cohesion
  • Coupling is a measure of the strength of the
    connections in a system.
  • Rigidity, fragility, immobility, dispensability
  • Cohesion is a measure of the logical sameness
    between parts how specific they are to a
    particular task.
  • Fragility, obscurity, dispensability, immobility

14
Tight Coupling
  • Tight Coupling means that parts are tightly
    connected. Pieces are not interchangeable.
  • class MyClass
  • private OracleDatasource ds
  • new OracleDatasource("uri",
  • "username", "password")
  • private Vector people new Vector()
  • // business logic

15
Tight Coupling
  • Tight Coupling means that parts are tightly
    connected. Pieces are not interchangeable.
  • class MyClass
  • private OracleDatasource ds
  • new OracleDatasource("uri",
  • "username", "password")
  • private Vector people new Vector()
  • // business logic

Can only use that particular database server.
What if you want to change to use a different
database type?
16
Loose Coupling
  • Loose Coupling means that parts are loosely
    connected. Pieces are easily interchangeable.
  • class MyClass
  • private DataSource ds
  • new OracleDatasource("uri", "username",
  • "password")
  • public void setDataSource(DataSource ds)
  • this.ds ds
  • // business logic

17
Loose Coupling
  • Loose Coupling means that parts are loosely
    connected. Pieces are easily interchangeable.
  • class MyClass
  • private DataSource ds
  • new OracleDatasource("uri", "username",
  • "password")
  • public void setDataSource(DataSource ds)
  • this.ds ds
  • // business logic

You can change what data source is used at any
time. For example, one for testing and one for
production.
DataSource is an interface. So you can use a
different kind of database, mock it out, put a
wrapper around a web service, etc.
18
Low Cohesion
  • Low Cohesion means that there is little that
    pieces have in common.
  • This tends to make systems
  • difficult to understand, because its not clear
    what the purpose of a module really is
  • difficult to maintain, because it is hard to know
    if youre working on all the right parts
  • difficult to reuse a module, because few other
    areas will need a random bunch of functionality

19
High Cohesion
  • High Cohesion means that a module is tightly
    focused on a particular task.
  • This tends to make systems
  • easy to understand, because its clear what the
    purpose of a module really is
  • easy to maintain, because it is easy to know if
    youre working on all the right parts
  • easy to reuse a module, because other areas can
    use exactly what they need with no extra overhead

20
  • Technologies

21
Test Driven Development
  • Test Driven Development (TDD) is the practice of
    using tests to design and verify your code.
  • Its much easier to fix a bug you did five
    minutes ago than five months ago.
  • A requirement isnt a requirement unless you can
    verify (test) that youve met it.
  • Because writing code that is quickly and easily
    testable requires that you make it highly
    cohesive and loosely coupled, doing TDD means
    that its easier to do things right than to do
    them wrong.

22
TDD Lifecycle
23
Interfaces and Abstract Classes
  • An interface is a class definition with no
    behavior given. Use of an interface requires
    implementing all of the methods of the interface.
  • An abstract class is a class that has behavior
    specified, but parts of the behavior have been
    left empty for further extension.

24
Why Are Interfaces Vital?
  • In Java a class can only be in a single hierarchy
    (single inheritance).
  • You can have a class implement an arbitrary
    number of interfaces, allowing a class to
    participate in orthogonal functional
    specifications. (e.g., It can be both a
    Collection and Serializable)
  • It forces you to focus on a class' contract
    rather than how it implements something.

25
Dependency Injection
  • How do you make sure that a class is not coupled
    to something else until it absolutely has to be?
  • By minimizing assumptions about the environment
    and handing it everything it needs at runtime.
  • This gives you the maximum possible mobility by
    giving as close to true plug and play as you
    can get.
  • What this means is that you can take something
    like a ShoppingCart and use it in a web server, a
    test case, a session bean, a message-driven bean,
    a stand-alone application, etc.

26
Dependency Injection Example
  • public class ShoppingCart
  • private Store store
  • private User user
  • private Collection items new ArrayList()
  • public ShoppingCart(Store store, User user)
    ...
  • public void addItem(Item item)
    items.add(item)
  • public void removeItem(Item item)
    items.remove(item)
  • public void checkOut()
  • store.sell(user, items)

27
Dependency Injection Containers
  • The primary problem with Dependency Injection is
    that it can be a hassle to manage making sure all
    the dependencies get injected correctly.
  • There are containers most notably the Spring
    Framework that handle this for you while having
    a near zero footprint in your code.

28
What Is A Mixin?
  • A mixin is code that is able to be mixed in
    with other code.
  • Allows you to get the benefits of multiple
    inheritance without many of the problems by using
    delegation.
  • For example, you can use Spring to mix in code
    for remoting, security, transactions, logging,
    etc.

29
Using Proxies to Do Mixins pt1
  • public interface Lockable
  • void lock()
  • void unlock()
  • boolean locked()
  • We would like to be able to make it so that we
    can add Lockable capabilities to any class,
    including ones that already are a part of a class
    hierarchy.
  • Again, you can add as many interfaces as you
    want.
  • What would be great is to be able to
    arbitrarily add interfaces and behavior to
    classes.

30
Using Proxies to Do Mixins pt2
  • public class LockMixin implements Lockable,
    InvocationHandler
  • private boolean locked
  • private Object obj
  • protected LockMixin(Object obj) this.obj
    obj
  • public void lock() this.locked true
  • public void unlock() this.locked false
  • public boolean locked() return this.locked
  • public static Object createInstance(Object obj)
  • Class inters obj.getClass().getInterfaces(
    )
  • Class interfaces new Classinters.length
    1
  • System.arraycopy(inters, 0, interfaces, 0,
    inters.length)
  • interfacesinters.length Lockable.class
  • return Proxy.newProxyInstance(LockMixin.class.
    getClassLoader(), interfaces, new
    LockMixin(obj))
  • // ...

31
Using Proxies to Do Mixins pt3
  • // ...
  • public Object invoke(Object proxy, Method
    method, Object args) throws Throwable
  • if (locked() method.getName().equals("add")
    )
  • throw new LockedException()
  • if (method.getDeclaringClass().equals(Lockable
    .class))
  • return method.invoke(this, args)
  • return method.invoke(obj, args)
  • List list new ArrayList()
  • List lockedList (List)LockMixin.createInstance(l
    ist)
  • lockedList.add("Hi")
  • ((Lockable)lockedList).lock()
  • lockedList.add("Bye") // throws LockedException

32
Packages as Modules
  • For anything more than very basic functionality,
    we need a larger unit than a class to define a
    module
  • In Java this is typically done with packages.
  • JAR files also act as fundamental modular units
    (made more useful with systems like Maven and
    OSGi)

33
Dependencies and Abstractions
  • Low-abstraction packages should depend upon
    high-abstraction packages.
  • Allows the high-abstraction packages to be reused
    independently.
  • The high-abstraction packages are then extensible
    to an open set of implementations.

34
No Cycles
  • There should never be a cyclic dependency between
    packages
  • A -gt B -gt A
  • This simple rule goes a long way toward
    encouraging loose coupling.
  • It is hard to do, even with practice.
  • But it is possible, with the Spring Framework
    being a major example.

Bad
35
Cyclic Dependencies
  • A cyclic dependency is an extremely tight
    coupling between modules, limiting your ability
    to make changes in the future.
  • No one does them on purpose, but they emerge
    (quickly) over time, and is a major code smell
    that the code is rotting.
  • Cycles between packages make it impossible to
    split the packages into separate JARs.

36
Conceptual Management Unit
  • Modules have a physical nature to them, both in
    terms of source management and deployment.
  • The conceptual nature of the module its logical
    cohesion must be maintained.
  • Both are important!
  • Using good tools, like Maven 2 and OSGi, make
    source management and deployment considerations
    much easier.

37
Cyclic Example 1
  • We have two classes, employee.Employee and
    manager.Manager.
  • The Employee has a instance of a Manager, and the
    Manager has a collection of Employees.

38
Cyclic Example 1
We have a cyclic dependency! The employee package
depends on the manager package, and vice versa.
  • We have two classes, employee.Employee and
    manager.Manager.
  • The Employee has a instance of a Manager, and the
    Manager has a collection of Employees.

39
Cyclic Example 1 - Fix
  • Move them into the same package.
  • If they were in separate packages because of
    several support classes, make Employee and
    Manager interfaces (high level abstractions) with
    implementations (low level abstractions) in
    subpackages.
  • person.Employee, person.Manager,
    person.employee.EmployeeImpl, person.employee.Vaca
    tionCalculator, etc.
  • Note that person.employee depends on person but
    not the other way around!

40
Cyclic Example 2
  • person.manager.CompanyCalendar is used by
    ManagerImpl.
  • person.employee.VacationCalculator is used by
    EmployeeImpl and uses CompanyCalendar.
  • person.manager.ManagerImpl needs to do some
    vacation calculations as well.

41
Cyclic Example 2
Calling VacationCalculator would introduce a
cycle!
  • person.manager.CompanyCalendar is used by
    ManagerImpl.
  • person.employee.VacationCalculator is used by
    EmployeeImpl and uses CompanyCalendar.
  • person.manager.ManagerImpl needs to do some
    vacation calculations as well.

Don't Repeat Yourself! (DRY) It's almost never a
good idea to cut paste.
42
Cyclic Example 2 - Fix
  • Move VacationCalculator and CompanyCalendar to a
    new package.

person
person.employee
person.manager
person
person.utils
person.employee
person.manager
43
  • Tools

44
JDepend
  • http//clarkware.com/software/JDepend.html
  • Will generate a number of different metrics about
    packages, including watching for cycles.
  • Can be used to generate reports, like
    jdepend-maven-plugin
  • Can be used in an automated environment, such as
    JUnit or FIT tests.

45
(No Transcript)
46
Maven 2
  • http//maven.apache.org/
  • A complete build system that encourages industry
    best practices
  • Easily manages module dependencies
  • Makes development of focused modules easy
  • Encourages keeping automated testing a strong
    part of development
  • Easily generates tons and tons of reports,
    including unit test results, test coverage, PMD,
    JDepend, etc.
  • and much, much more

47
FindBugs
  • http//findbugs.sourceforge.net/
  • A very nice (and free) static analyzer that will
    find an amazing number of bugs and future bugs
    for you.

48
Q A
Write a Comment
User Comments (0)
About PowerShow.com