29
1 Advance Patterns and Frameworks Frameworker's Dilemma Peter Sommerlad, SS2005

1 Advance Patterns and Frameworks Frameworker's Dilemma Peter Sommerlad, SS2005

Embed Size (px)

Citation preview

1

Advance Patterns and FrameworksFrameworker's Dilemma

Peter Sommerlad, SS2005

Frameworker's Dilemmas Advanced Patterns and Frameworks 2

Overview

stable Interfaces vs. Framework Evolution forces pulling in opposite directions

simple stable and generic Interfaces configurabilityEclipse's approach

dilemma explanation plug-in architecture extension interface

Frameworker's Dilemmas Advanced Patterns and Frameworks 3

From Procedural towards Framework Programming

source: Inside Taligent Technology

Frameworker's Dilemmas Advanced Patterns and Frameworks 4

Proposed benefits of application frameworks

Less code to write. More reliable and robust code. More consistent and modular code. More focus on areas of expertise, less focus

on areas of system compatibility. Generic solutions that can be reused for

other, related problems. Improved maintenance and orderly program

evolution. Improved integration of related programs.

source: Inside Taligent Technology 1995

Frameworker's Dilemmas Advanced Patterns and Frameworks 5

Framework usage

Framework users implement application code by subclassing of framework classes or implementing their predefined interfaces by application components.

configuration of predefined components as well, but that is more like library usage.

Inheritance is one of the strongest couplings between 2 components

why? what can happen?

Frameworker's Dilemmas Advanced Patterns and Frameworks 6

Application lock-in ?

strong coupling to framework components hinders application portability:

How do I separate my application specific code and concepts from too many details of the framework, so that I can port it to the next version of the framework or even another environment?

own thin decoupling layer couple to framework environment nevertheless build my own portable framework

Frameworker's Dilemmas Advanced Patterns and Frameworks 7

Framework lock-in

There are two reasons for lack of framework evolution and improvement:

no application uses the framework no users, no need to improve or evolve no experience on what to improve

one or more applications use the framework changing the framework risks breaking applications applications produce work-arounds to framework

deficiencies and break when those "features" are fixed

Frameworker's Dilemma

Frameworker's Dilemmas Advanced Patterns and Frameworks 8

Potential Ways out of the Frameworker's Dilemma (1)

Think very hard up-front very very hard, may work a little bit the second

or third time requires very experienced, very bright persons without concrete applications, it is hard to

decide what to abstract and generalize in a framework

can lead to expensive and unusable over-engineered frameworks (e.g. Taligent, IBM's San Francisco)

takes too long to hit window of opportunity might still be sub-optimal to use

Frameworker's Dilemmas Advanced Patterns and Frameworks 9

Potential Ways out of the Frameworker's Dilemma (2)

Don't care too much about your framework users (= application developers)

lay the burden of porting applications to the application's developer

provide many good and useful new features to make porting a "must"

might provide porting tools and guidelines support old versions indefinitely or fight hard to

keep it backward compatible framework user's might switch to other

offerings

Frameworker's Dilemmas Advanced Patterns and Frameworks 10

Potential Ways out of the Frameworker's Dilemma (3)

Be a good citizen and let framework users participate

social process can help, e.g. by giving users time to migrate deprecated interfaces

tendency for indefinite backward compatibility with a strong user community

design by commitee is almost always over-engineered and brittle

might require explicit migration training and coaching

Frameworker's Dilemmas Advanced Patterns and Frameworks 11

Potential Ways out of the Frameworker's Dilemma (4)

Can technology or methodology help? not totally, but can improve situation

simple interfaces tendency to be more stable

flexible interfaces tendency to be more stable

configurability less direct code-dependencies

patterns extension interface

Frameworker's Dilemmas Advanced Patterns and Frameworks 12

Simple InterfacesWebDisplay's Action class

Only DoAction() needs to be implemented two simple generic parameters

class Action : public NotCloned{public:

Action(const char *name);virtual bool DoAction(String &transitionToken, Context&)

{ return false; }virtual bool DoExecAction(String &transitionToken,

Context& ctx, const ROAnything &config) { return DoAction(transitionToken,ctx); }

static bool ExecAction(String &transitionToken, Context &c);static bool ExecAction(String &transitionToken,

Context &c, const ROAnything &config); RegCacheDef(Action); // FindAction()

};

Frameworker's Dilemmas Advanced Patterns and Frameworks 13

Simple InterfacesWebDisplay's Renderer

Only RenderAll() needs to be implemented three simple generic parameters

Simple constructor needing a name

class Renderer : public NotCloned{public:

Renderer(const char *name);//!rendering hook; overwrite this method in subclasses//!generates output on reply driven by config using context//! \param reply stream to generate output on//! \param c Context to be used for output generation//! \param config configuration which drives the outputvirtual void RenderAll(ostream &reply,

Context &c, const ROAnything &config);

//... some scaffolding methods non-virtual

Frameworker's Dilemmas Advanced Patterns and Frameworks 14

Simple Interfacesjunit

Test asks for void run() most simple method

TestCase for three similar simple methods reflection allows all void testXXX() methods

public abstract class TestCase implements Test {... public void run() { setUp(); runTest(); tearDown();}protected void runTest() throws Throwable {}protected void setUp() throws Exception {}protected void tearDown() throws Exception {}...}

Frameworker's Dilemmas Advanced Patterns and Frameworks 15

Flexible Interfaces

Encapsulate Context Pattern (Allan Kelly)A system contains data, which must be generally

available to divergent parts of the system, but we wish to avoid using long parameter lists to functions or global data; therefore, we place the necessary data in a Context container and pass this object from function to function.

Other patterns:Property List, Anything

implementation options for Encapsulate Context

Frameworker's Dilemmas Advanced Patterns and Frameworks 16

Encapsulate Context

Frameworker's Dilemmas Advanced Patterns and Frameworks 17

Property List as Parameters

Property Lists as parameters. Passing a property list as a parameter allows a client component to extend the amount of data passed to an operation at will. If you want to keep stable interfaces, shared by different teams, but are still heavily under development, propertylists as parameters or attributes can be a real life-safer.

see also Anything benefits!

Frameworker's Dilemmas Advanced Patterns and Frameworks 18

Flexible Plug Ins

Eclipse also suffers from the Frameworker's Dilemma.

However, Kent Beck and Erich Gamma explain in their book Contributing to Eclipse how Eclipse's framework leverages patterns to overcome this dilemma

Note: examples from this book are based on Release 2.x of Eclipse, 3.x uses similar patterns but some different classes/interfaces

Frameworker's Dilemmas Advanced Patterns and Frameworks 19

Eclipse (2.x) Plugin Exampleaus [BeckGamma]

org.eclipse.resources provides abstractions like IFile, IFolder, IProject

separation of concept from UI developing a File class requires to implement

IFile as well as a corresponding UI interface, e.g., IPropertySource for the properties editor

IFile could extend IPropertySourcebut results in a bloated interface implementing such a service is an

implementation detail, which breaks the API of IFile if added later on

IFile shouldn't have to know about the Properties view

Frameworker's Dilemmas Advanced Patterns and Frameworks 20

Example for Extension Interface

Eclipse needs a mechanism that allowsadding a service interface to a component

without exposing it in the component's type allowing future feature additions/changes

without breaking client codeadding behavior to preexisting types such as

IFile allow even unforseen extensions of a

component

Frameworker's Dilemmas Advanced Patterns and Frameworks 21

Extension Interface Pattern

The Extension Interface design pattern allows multiple interfaces to be exported by a component, to prevent bloating of interfaces and breaking of client code when developers extend or modify the functionality of the component.

Frameworker's Dilemmas Advanced Patterns and Frameworks 22

Eclipse's IAdaptable

IAdaptable defines a Method Object getAdapter(Class a)

corresponds to getExtension of the Extension Interface pattern

usage:

private IPropertySource getPropertySource(Object object) {//...else if (object instanceof IAdaptable) result = (IPropertySource) ((IAdaptable)object).getAdapter(IPropertySource.class);

sources.put(object, result);return result;}

Frameworker's Dilemmas Advanced Patterns and Frameworks 23

IAdaptable usage in Eclipse

A class wants to provide additional interfaces without exposing them in the API

getAdapter implemented internally in the class adding a new interface requires modification of

getAdapter implementation

A class is augmented from the outside to provide additional services

no code change required

public class FileSystemElement implements IAdaptable {//...public Object getAdapter(Class adapter) {if (adapter == IWorkbenchAdapter.class) { return workbenchAdapter;}//defer to the platformreturn Platform.getAdapterManager().getAdapter(this, adapter);}

Frameworker's Dilemmas Advanced Patterns and Frameworks 24

How to provide configurable adaptation

IAdapterManager – AdapterManager keeps registry of available AdapterFactories for

a specific IAdaptable class IAdapterFactory

creates an IAdaptable for a given object together with a given target IAdaptable subclass Eclipse 3.x contains an IAdapterFactoryProxy, so that

Factories are loaded on demand like configured

public Object getAdapter(Class adapter) {return Platform.getAdapterManager().getAdapter(this, adapter);}

Frameworker's Dilemmas Advanced Patterns and Frameworks 25

Example Adapter Factory (Eclipse 2.1)

class WorkbenchAdapterFactory implements IAdapterFactory {//...public Object getAdapter(Object o, Class adapterType) { if (adapterType.isInstance(o)) { return o; } if (adapterType == IWorkbenchAdapter.class) { return getWorkbenchElement(o); } if (adapterType == IPersistableElement.class) { return getPersistableElement(o); } if (adapterType == IElementFactory.class) { return getElementFactory(o); } if (adapterType == IActionFilter.class) { return getActionFilter(o); } return null;}

Frameworker's Dilemmas Advanced Patterns and Frameworks 26

Patterns dealing with IAdaptable

IAdaptable

getAdapter(Class)

SomeInterface

PlatformObject

getAdapter(Class)

IAdapterManager

getAdapter(Object,Class)

IAdapterFactory

getAdapter(Object,Class)

AdapterFactoryProxy

getAdapter(Object,Class)

*

*

RootInterface ExtensionInterface

Component Manager

Abstract Factory

Proxy

Frameworker's Dilemmas Advanced Patterns and Frameworks 27

Discussion Eclipse's Extension Mechanism

Multiple Adapters for the same type most specific adapter wins following class/interface

hierarchy Stateless Adapters are easier to manage

better have stateless adapters, keep state in the adapted objects

what pattern is usable for keeping such flexible state?

Which adapters are supported? only feasible by documenting and try&error

Adapter negotiation might be needed different adapters can be usable in a concrete situation

Reduced programming comfort casting and null checks required

Frameworker's Dilemmas Advanced Patterns and Frameworks 28

Searching Eclipse for patterns...

create a plug-in project (for example) and/or import org.eclipse packages, e.g. core,

jdt.core, etc.Navigate->Open Type try pattern matching:

*visitor *adaptor *proxy *factory

Frameworker's Dilemmas Advanced Patterns and Frameworks 29

Literatur

Kent Beck, Erich Gamma: Contributing to Eclipse: Principles, Patterns and Plug-Ins