+ All Categories
Home > Documents > Mark Pollack Principal Software Engineer SpringSource ARC305.

Mark Pollack Principal Software Engineer SpringSource ARC305.

Date post: 26-Dec-2015
Category:
Upload: donald-laurence-porter
View: 223 times
Download: 4 times
Share this document with a friend
Popular Tags:
54
Transcript
Page 1: Mark Pollack Principal Software Engineer SpringSource ARC305.
Page 2: Mark Pollack Principal Software Engineer SpringSource ARC305.

Architecture Refactoring: Improving the Design of Existing Application Architectures

Mark PollackPrincipal Software EngineerSpringSourceARC305

Page 3: Mark Pollack Principal Software Engineer SpringSource ARC305.

Session Objectives and Agenda

Architectural Decay

Refactoring Overview

Architectural Refactoring

Page 4: Mark Pollack Principal Software Engineer SpringSource ARC305.

The Problem: Architectural Decay

System works but…Difficult to meet new requirements

Lacks in quality attributes

MaintainabilityExtensibilityPerformance

"Brownfield" development

Component 1

Data Access Layer

Presentation Layer

Component 2

Component 3

Component 5 Component 6

Component 4

Page 5: Mark Pollack Principal Software Engineer SpringSource ARC305.
Page 6: Mark Pollack Principal Software Engineer SpringSource ARC305.

How did This Happen?

As software evolves, architecture decaysThe original design

Gets lost in sea of changesCompromised by shortcutsWas never meant to address current requirements

New development is done 'fearfully'Design flaws are not addressed directlyNew features are added by cut-n-paste of old onesThose with the original system knowledge haveManagement fearful of cost/time to make changes

Page 7: Mark Pollack Principal Software Engineer SpringSource ARC305.

What can be done about it?

Apply refactoring principals to the architectureCode refactorings are more well known

Classify recurrent problems and apply 'recipes' to implement best practices

Refactoring is part of an iterative development processes

Aims for incremental improvements in each cycleInclude the architecture during each cycle

This talk will introduce architectural refactoringsShow by example how to apply

Page 8: Mark Pollack Principal Software Engineer SpringSource ARC305.

Code Refactoring

"…the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure"

- Martin Fowler

Page 9: Mark Pollack Principal Software Engineer SpringSource ARC305.

Refactoring as a process

Provides a well defined, generally applicable transformational processCatalogs common problemsSpecifies 'recipes' so that best practices can be incrementally appliedBorn out of experienceProcess can be applied to other artifacts

UML Diagrams, databases, test plansCollectively … the architecture

Page 10: Mark Pollack Principal Software Engineer SpringSource ARC305.

Refactoring Categories

Code Level – M. FowlerDatabases – S. AmblerDesign Patterns - J. KerievskyArchitecture – M. Stal

Apply changes to structure but not functionalityDistinct process from ReengineeringTypically encompass several other refactoring categories

Page 11: Mark Pollack Principal Software Engineer SpringSource ARC305.

How a Refactoring is 'Born'

They are discovered, not inventedCome from 'smells'Smells that violate common principals

Separation of Concerns Don't Repeat YourselfYou Ain't Gonna Need It

Page 12: Mark Pollack Principal Software Engineer SpringSource ARC305.

Architecture Smells

Shortcuts across application layersApplication feels like a 'big ball of mud'An existing layer should be split into two or more logical layersDependency cycles Business logic is tightly coupled to

non-functional requirements

Page 13: Mark Pollack Principal Software Engineer SpringSource ARC305.

Architecural Refactoring Catalog (I)Courtesy: Michael Stal

Rename EntitiesRemove DuplicatesIntroduce Abstraction HierarchiesRemove Unnecessary AbstractionsSubstitute Mediation with AdaptationBreak Dependency CyclesInject DependenciesInsert Transparency LayerReduce Dependencies with Facades

Merge SubsystemsSplit SubsystemsEnforce Strict LayeringMove EntitiesAdd StrategiesEnforce SymmetryExtract InterfaceEnforce ContractProvide Extension InterfacesSubstitute Inheritance with DelegationProvide Interoperability Layers

Page 14: Mark Pollack Principal Software Engineer SpringSource ARC305.

Architecural Refactoring Catalog (II)Courtesy: Michael Stal

Introduce AspectsIntegrate DSLsAdd Uniform Support to Runtime AspectsAdd Configuration SubsystemIntroduce the Open/Close PrincipleOptimize with CachingReplace SingletonSeparate Synchronous and Asynchronous ProcessingReplace Remote Methods with Messages

Add Object ManagerChange Unidirectional Association to Bidirectional

Page 15: Mark Pollack Principal Software Engineer SpringSource ARC305.

Architectural Refactorings in action

Apply as part of a controlled iterative development processGoal is to improve or introduce a set of quality attributesArchitect's role to

Determine the order of refactoringsApply the refactoringsEnsure quality

Page 16: Mark Pollack Principal Software Engineer SpringSource ARC305.

Example Application

Microsoft's StockTrader example application

Enforce Strict LayeringInject DependenciesIntroduce Aspects

Trade Service Façade (ASMX)

Data Access Layer

WPF

Trade Service Façade (WCF)

Trade Service

ASP.NET

A

A

A A

Page 17: Mark Pollack Principal Software Engineer SpringSource ARC305.

Prequisite: Create Integration Tests

One must take steps to ensure qualityHow do we know the refactorings are correct?

Does new architecture still meet the specificationNeed integration tests to run as a regressionAutomation is essentialSeveral tools and techniques can helpActs as a safety net

Page 18: Mark Pollack Principal Software Engineer SpringSource ARC305.

Automated Testing Toolbox

Code focused testing frameworksMSTest, NUnit, mbUnit, etc…

UI focused testing productsWinRunner, LoadTest, Ranorex, Selenium, …

Continuous IntegrationVSTS, CruiseControl, Hudson

Code coverageVSTS, NCover

Build toolsMSBuild, NAnt.

Page 19: Mark Pollack Principal Software Engineer SpringSource ARC305.

Integration TestsMark PollackPrincipal Software EngineerSpringSource

demo

Page 20: Mark Pollack Principal Software Engineer SpringSource ARC305.

ProblemLack of strict layering leads to tight coupling

Refactoring : Enforce Strict Layering

ContextNot clear where to place new functionality

Application

Component 3.1 Component 3.1 Component 3.1

Component 2.1 Component 2.2

Component 1.1 Component 1.1 Component 1.1

Layer 2

Layer 3

Layer 1

BrokenLayering

ProblemImpediment to more fine grained testing

SolutionRedesign - new layers, moving of functionality, break data format dependencies

Page 21: Mark Pollack Principal Software Engineer SpringSource ARC305.

Layering Toolbox

Visualization and enforcement toolsVSTS 2010SotoArcDependency Structure Matrix (DSM)

NDependLattix

Testing Frameworks

Page 22: Mark Pollack Principal Software Engineer SpringSource ARC305.

Refactoring: Inject Dependencies

ContextObject needs to create and use collaborating objects

Component 1private Component2 c2;public Init() {

S1 s1 = new S1(...); S2 s2 = new S2(...); c2 = new C2(s1,s2); }

Component2

S1

S2

DIContainer

ProblemThe object should not be dependent on knowledge of how to create its collaborators

ProblemHand coded factories are impractical

SolutionSeparate the responsibility of creating collaborating objects to a Dependency Injection (DI) container

private Component2 c2;

public Component2 C2 { set { . . . }}

private Component2 c2;

public Component1 (Component2 c2){

this.c2 = c2;}

Page 23: Mark Pollack Principal Software Engineer SpringSource ARC305.

The Quick Guide to DI

DI containers act as generalized object factoriesHow to configure a DI container with object creation and configuration rules?Provide metadata

XMLAttributes Fluent API

Page 24: Mark Pollack Principal Software Engineer SpringSource ARC305.

Autofac Configuration (XML)

<autofac defaultAssembly="Trade.DALSQLServer"> <components> <component type="Trade.BSI.TradeService, " service="Trade.BSC.ITradeServices, Trade.BSC"/>

<component type="Trade.DALSQLServer.Order" service="Trade.IDAL.IOrder, Trade.IDAL" />

<component type="Trade.DALSQLServer.Customer" service="Trade.IDAL.ICustomer, Trade.IDAL"/>

<component type="Trade.DALSQLServer.MarketSummary" service="Trade.IDAL.IMarketSummary, Trade.IDAL"/>

</components>

</autofac>

Page 25: Mark Pollack Principal Software Engineer SpringSource ARC305.

Autofac Configuration (Fluent API)

var builder = new ContainerBuilder();

builder.Register<TradeService>() .As<ITradeServices>() .ContainerScoped();

builder.Register<Order>() .As<IOrder>() .ContainerScoped();

builder.Register<Customer>() .As<ICustomer>() .ContainerScoped();

builder.Register<IMarketSummary>() .As<MarketSummary>() .ContainerScoped();

Page 26: Mark Pollack Principal Software Engineer SpringSource ARC305.

NInject (Attributes) public class TradeService : ITradeServices {

[Inject] public TradeService(IOrder dalOrder, ICustomer dalCustomer, IMarketSummary dalMarketSummary) { this.dalOrder = dalOrder; this.dalCustomer = dalCustomer; this.dalMarketSummary = dalMarketSummary; } }

IKernel kernel = new StandardKernel( new InlineModule( x => x.Bind<ITradeServices>().To<TradeService>(), x => x.Bind<IOrder>().To<Order>(), x => x.Bind<ICustomer>().To<Customer>(), x => x.Bind<IMarketSummary>().To<MarketSummary>()));

Page 27: Mark Pollack Principal Software Engineer SpringSource ARC305.

Unity Configuration (XML)

<type type="Trade.BSC.ITradeServices, Trade.BSC" mapTo="Trade.BSI.TradeService, Trade.BSI "> <lifetime type="singleton" /> <typeConfig extensionType="TypeInjectionElement, Unity.Configuration"> <constructor> <param name="orderDal" parameterType="Trade.IDAL.IOrder, Trade.IDAL"/> </constructor> </typeConfig> </type>

<type type="Trade.IDAL.IOrder" mapTo="Trade.DALSQLServer.Order, Trade.DALSQLServer "> <lifetime type="singleton" /> </type>

Page 28: Mark Pollack Principal Software Engineer SpringSource ARC305.

Spring Configuration

<object id="tradeService" type="Trade.BSI.TradeService, Trade.BSI"> <constructor-arg ref="orderDal"/> <constructor-arg ref="customerDal"/> <constructor-arg ref="marketSummaryDal"/></object>

<object id="orderDal" type="Trade.DALSQLServer.Order, Trade.DALSQLServer"> <property name="ConnString" value="${orderDalConnStr}"/></object>

<object id="customerDal" type="Trade.DALSQLServer.Customer"> <property name="ConnString" value="${customerDalConnStr}"/></object>

<object id="marketSummaryDal" type="Trade.DALSQLServer.MarketSummary"> <property name="ConnString" value="${marketDalConnStr}"/> </object>

Page 29: Mark Pollack Principal Software Engineer SpringSource ARC305.

DI and the Runtime Environment

DI containers provide integration support to many common runtime environments

WCFCustom ServiceHost

ASP.NETCustom HttpModule/PageHandlerFactory

ASP.NET MVCTest frameworks

Custom base class or attribute extensions

Page 30: Mark Pollack Principal Software Engineer SpringSource ARC305.

Example: DI for ASP.NET

<object type="StockTrade.aspx"> <property name="TradeService" ref="tradeService"/></object>

Register custom HttpModule and HttpHandler

Page 31: Mark Pollack Principal Software Engineer SpringSource ARC305.

Example: DI for ASP.NET MVC

Register custom Controller Factory

<object name="controller.StockTrade" type="StockTrader.StockController, StockTrader" singleton="false">

<property name="TradeService" ref="tradeService"/>

</object>

Page 32: Mark Pollack Principal Software Engineer SpringSource ARC305.

Example: DI for WCF

Register custom Service Host

<object name="wcfTradeService" type="Trade.StockTraderWebApplication.BusinessServiceClient

singleton="false"> <property name="TradeService" ref="tradeService"/> </object>

Page 33: Mark Pollack Principal Software Engineer SpringSource ARC305.

Inject DependenciesMark PollackPrincipal Software EngineerSpringSource

demo

Page 34: Mark Pollack Principal Software Engineer SpringSource ARC305.

Benefits

Application is more easily testableComponents not responsible for self configurationNo custom factories to maintain

Application becomes collection of loosely coupled componentsDivide and conquer implementation approach

Test layers individually, then assembleCan incrementally adopt dependency injectionImproved design automatically 'creeps' in

Page 35: Mark Pollack Principal Software Engineer SpringSource ARC305.

Refactoring: Introduce Aspects

ContextDecouple components from the surrounding technical infrastructure

ProblemBusiness logic is tied to a technology decreasing its portability and 'life expectancy'Excessive cut-n-paste reuse

SolutionImplement concerns separatelyBring concerns together using Aspect Oriented Programming (AOP)

Page 36: Mark Pollack Principal Software Engineer SpringSource ARC305.

Non Functional Requirements

Often expressed in terms such asthe service layer should be transactionalA business service that fails with a particular exception failure can be retried Secure every business method invocation

The 1:1 principal"There should be a clear, simple, 1:1 correspondence between design-level requirements and the implementation"

Page 37: Mark Pollack Principal Software Engineer SpringSource ARC305.

The AOP Value Proposition

Achieve separation of concernsCross cutting concerns in one componentBusiness functionality in another component

But still recombine business and technical requirements into a complete application

Page 38: Mark Pollack Principal Software Engineer SpringSource ARC305.

System Evolution Without AOP

BankService

Codescattering

Codetangling

TransactionsSecurity

Logging

CustomerService ReportingService

Page 39: Mark Pollack Principal Software Engineer SpringSource ARC305.

System Evolution With AOP

TransactionAspect

SecurityAspect

LoggingAspect

BankService CustomerService

ReportingService

Page 40: Mark Pollack Principal Software Engineer SpringSource ARC305.

AOP Terminology

All the possible places one could 'insert' functionality

Join pointWhat is the functionality?

AdviceWhere to insert?

PointcutWhat + Where =

Aspect

Page 41: Mark Pollack Principal Software Engineer SpringSource ARC305.

AOP Implementation Approaches

Dynamic ProxyBehavior added at run time'Auto generation' of wrapper classes

IL WeavingBehavior added at compile timeAssembly rewriting

AOP + DI in combination is natural and powerful

Page 42: Mark Pollack Principal Software Engineer SpringSource ARC305.

Example: Transation Management

How to best satisfy the requirement that the service layer should be transactionalAdding transactional boilerplate code in the service layer is prone to errorsSolution: Declarative Transaction Management

Use meta data to specify transactional boundarySelect among several transaction APIs

Page 43: Mark Pollack Principal Software Engineer SpringSource ARC305.

Transaction Management Proxy

AOP ProxyAOP Proxy

TradeService(target)

TradeService(target)

TransactionAdviceTransactionAdvice

ITradeServicesITradeServicesBuy

ADO.NET Transaction Manager

ADO.NET Transaction Manager

begin commit

System.TransactionsTransaction ManagerSystem.TransactionsTransaction Manager

NHibernate Transaction Manager

NHibernate Transaction Manager

Page 44: Mark Pollack Principal Software Engineer SpringSource ARC305.

Introduce AspectsMark PollackPrincipal Software EngineerSpringSource

demo

Page 45: Mark Pollack Principal Software Engineer SpringSource ARC305.

Introduce Aspects: Benefits

Clean simple business codeImplementation looks more like requirementsSystem now has 'conventions' in it

"this namespace is transactional"Ensures we meet requirement

No errors of omissionProvides a contract with developers

they know what to expect.

Just the beginning…Add caching to DAO layer, monitoring etc.

Page 46: Mark Pollack Principal Software Engineer SpringSource ARC305.

Conclusion

Refactoring is not constrained to code but is applicable to architectureYou can change for the better incrementallyRegression tests are essentialStrict layering is the first things to tackleUse DI and AOP to aid in many architectural refactorings

Page 47: Mark Pollack Principal Software Engineer SpringSource ARC305.

Refactoring: Improving the Designof Existing Code, Addison-Wesley, 1999

Refactoring Databases: EvolutionaryDatabase Design, Addison-Wesley, 2006

http://stal.blogspot.comOOPSLA Conference Tutorials/Podcasts

Kerievsky, Joshua: Refactoring to Patterns,Addison-Wesley, 2004

Resources

Page 48: Mark Pollack Principal Software Engineer SpringSource ARC305.

Brownfield Application Development in .NET, Manning 2009

Resources

Page 49: Mark Pollack Principal Software Engineer SpringSource ARC305.

Related Content

ARC201 - A Lap aroudn Team System 2010 Architecture Edition

ARC303 – Architectural Strategies for Increased Discovery, Integration, and Modularity

Page 50: Mark Pollack Principal Software Engineer SpringSource ARC305.

Track Resources

Michael Stahl's Blog - http://stal.blogspot.com

Wikipedia entries for Depenency Injection and Aspect Oriented Programming

Spring for .NET Framework - http://www.springframework.net

Page 51: Mark Pollack Principal Software Engineer SpringSource ARC305.

www.microsoft.com/teched

Sessions On-Demand & Community

http://microsoft.com/technet

Resources for IT Professionals

http://microsoft.com/msdn

Resources for Developers

www.microsoft.com/learningMicrosoft Certification and Training Resources

www.microsoft.com/learning

Microsoft Certification & Training Resources

Resources

Page 52: Mark Pollack Principal Software Engineer SpringSource ARC305.

question & answer

Page 53: Mark Pollack Principal Software Engineer SpringSource ARC305.

Complete an evaluation on CommNet and enter to win!

Page 54: Mark Pollack Principal Software Engineer SpringSource ARC305.

© 2009 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS,

IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.


Recommended