Efficient Code Organisation
-
date post
17-Oct-2014 -
Category
Technology
-
view
1.074 -
download
2
description
Transcript of Efficient Code Organisation
By: Lennart Jörelid
JavaOne 2012 -‐ BOF6357
By: Lennart Jörelid
¡ Lennart Jörelid, jGuru Europe AB § Builds large-‐scale JEE systems § Enterprise and OSS dev/arch since 1995
By: Lennart Jörelid
1: Problem The costly on-‐boarding process
2: Usability Projects & usability engineering
3: Tooling Structuring & enforcing projects
4: Q & A Q & A
By: Lennart Jörelid
¡ Java programming in itself § Assumtion: You know Java, Projects … & Maven
¡ In-‐depth Human Computer Interaction / Usability Engineering and Design § Instead, this talk serves to inspire you § Apply usability engineering to areas where it is seldom considered § Developers are also users … of VCSs/projects/tooling
By: Lennart Jörelid
1: Problem
Terms, concepts, patterns
By: Lennart Jörelid
We aim for end-‐user quality and usability in
our software.
Do we also provide usability for ourselves?
Do you have useable and well-‐designed codebases?
By: Lennart Jörelid
Frequency … moved between projects a lot?
Relevance … felt introduction was great?
Experience … was helped by tooling to reduce the need for reading/mentoring?
Characteristics … works/ed in big projects?
By: Lennart Jörelid
Application … designed APIs using principles of HCI?
Consequence … applied usability to design VCS structure?
Tooling … set up Maven plugins to give feedback to developers when guidelines are broken?
Usability … knows or studied usability engineering?
By: Lennart Jörelid
¡ Introduction of new coworkers is too costly § Takes too long; inefbicient domain explanation
¡ Difbicult to bind/understand/apply standards § Where are the active standards debinitions?
§ ”Wade through the Wiki/Sharepoint syndrome”
§ Limited feedback before committing code § Limited tooling enforcing your development & design
¡ VCS structured for builds, not assist understanding § Domain ó VCS ó Build system disconnect
§ ”Where is the domain model for FooBar”?
By: Lennart Jörelid
Organisation Presentation
[Project] Manager
Product Presentation
[Biz] Architect
[Scrum] Team Presentation
Scrum Master
Learning curve [Yourself]
Wiki, Templace, …
Productivity [Yourself]
OSS
By: Lennart Jörelid
Scrum Master
Learning curve
Organisation Presentation
[Project] Manager
Product Presentation
[Biz] Architect
[Scrum] Team Presentation
[Yourself]
Wiki, Templace, …
Productivity [Yourself]
Documents
By: Lennart Jörelid
Time-‐consuming/costly to produce When written: did you document all of it?
Difbicult to bind when needed When found: is it updated/current?
Time-‐consuming/costly to consume When read: do you understand it all?
By: Lennart Jörelid
¡ Reduce the need to read documents § Reduced reading time ó increased pace § Re-‐use component patterns
¡ Reduce the number of concepts in a VCS § Aim for manageable ”mouthfuls” manageable by the short-‐term memory
§ Enforce consistency in naming, structure etc. § … to comply with your development guidelines…
By: Lennart Jörelid
Usability, Project structure and Learning
2: Usability
By: Lennart Jörelid
¡ Apply usability to project design § Originate from the human mind & learning § Adhere to standard design principles [HCI]
¡ This requires some [basic] knowledge of § … the learning process § … available design principles § … usability engineering
By: Lennart Jörelid
Sensory Input
Short-‐term Memory
Long-‐term Memory
”7 ± 2” ~ seconds
”Unlimited” Indefinite ~ instant
By: Lennart Jörelid
Visibility
Affordance
What does X do?
How do I use X?
Feedback I see the state of X.
Constraint I can’t use X in a certain way.
Consistency I use X2 like I used X1.
By: Lennart Jörelid
¡ Efbicient projects à Trees of Components § Move towards 7±2 folders visible § Design principles applied
”Component” is really overloaded. How do we define
it here?
By: Lennart Jörelid
Pattern A way to sustainably reduce dependency tanglement Shared patterns in the codebase
VCS structure & Naming pattern Coding & semantic standard
Dependency Ctrl A way to sustainably reduce dependency tanglement Requirement in enforcing coding standards
Depdendency pattern & -‐classification Enforcement rules
Simplibication A way to promote better architectural overview A means to reduce scope and complexity
Common classification of projects Compliance with design principles
By: Lennart Jörelid
Accessed via an API and Model • 2 public [Maven] projects • C.f. OSGi, Jigsaw, JBoss modules, …
API dependency imported by client • Implementation projects injected • Implementation types unavailable during development • è Loose coupling (Good!)
By: Lennart Jörelid
Dependencies in Sw Component
foo
Structure in VCS
foo-‐model
foo-‐api
foo-‐impl-‐bar
foo-‐impl-‐gnat
foo-‐spi-‐gnu
No model. ó ”Library”
Model. ó ”Domain Component”
foo-‐example
Copy & paste code
By: Lennart Jörelid
x-‐model Component en))es (annotated POJOs) holding component (business) state No dependencies to other component projects
x-‐api Component service specifica)on (i.e. Interfaces, Excep)ons and Abstract classes). Depends only on the Model Project
x-‐impl-‐y Component service implementa)on Depends on the API, and any required external dependencies
x-‐example Project holding runnable, well-‐documented code code illustra)ng the use of the API. (copy/paste)
By: Lennart Jörelid
¡ ”Relatively few” (7±2) components to grasp § Simplibies learning and augments overview
§ Important to support this in IDEs… poor Eclipse-‐users
By: Lennart Jörelid
Components
Component Projects
3 impl projects!
By: Lennart Jörelid
¡ Use SoftwareComponent concept § Visibility, Consistency, Affordance
¡ Learning Process § Grouping and Design of VCS / software repo
¡ Tooling
§ Constaints, Feedback
By: Lennart Jörelid
Designing efbicient projects Enforcing standards & design
3: Tooling
By: Lennart Jörelid
¡ Tooling reduce the need for documentation § ”Enforce if possible, Document if required”
¡ Conbigure tooling in a shared Codestyle project § Global dependency; used in build cycle debinition § Same code validation on workstations and CI server
¡ Several Maven plugins exist § Enforcer plugin, Checkstyle plugin, Cobertura plugin, Findbugs plugin, CPD plugin, …
By: Lennart Jörelid
¡ Maven Enforcer Plugin [Build criteria] § Uses stock and custom rules (Java classes)
§ Custom rules frequently needed
¡ Maven Checkstyle Plugin [Code style] § Uses checkstyle.xml rule conbiguration
§ Seldom need to write custom checkstyle rules
¡ Maven Cobertura Plugin [Test coverage] § Uses unit tests and conbiguration
§ No need to write custom plugin rules
By: Lennart Jörelid
Enforcer Conbiguration & custom rules
Code Quality Checkstyle/PMD/Findbugs conbig.
Cobertura Unit test Coverage reports
By: Lennart Jörelid
<plugin> <artifactId>maven-‐enforcer-‐plugin</artifactId> <version>1.3.1</version> <executions> <execution> <id>enforce-‐imports</id> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <requireMavenVersion> <version>[3.0.5,)</version> </requireMavenVersion> <requireJavaVersion> <version>${jdk.version}</version> </requireJavaVersion> <validateProjectTypes implementation=“se.jguru.nazgul.tools.codestyle. enforcer.rules.ValidateProjectType”/> </rules> </configuration> </execution> </executions>
…
Plugin goal definition
Stock rules
Custom rules
By: Lennart Jörelid
… <dependencies> <dependency> <groupId>se.jguru.nazgul.tools.codestyle</groupId> <artifactId>nazgul-‐codestyle</artifactId> <version>2.0.9</version> </dependency> </dependencies>
</plugin>
Custom rules Dependency project
By: Lennart Jörelid
Rule Meaning bannedDependencies Enforces that excluded dependencies aren't included. bannedPlugins Enforces that excluded plugins aren't included. dependencyConvergence Ensure all dependencies converge to the same
version. evaluateBeanshell Evaluates a beanshell script. requireReleaseDeps Enforces that no snapshots are included as
dependencies. requireReleaseVersion Enforces that the artifact is not a snapshot. requireMavenVersion Enforces the Maven version.
By: Lennart Jörelid
Create Project Create a tool project holding your rules
Imports Import enforcer-‐api & maven deps
Implement 1 class per rule type
Usage Use the enforcement rules in your poms
By: Lennart Jörelid
<dependency> <groupId>org.apache.maven.enforcer</groupId> <artifactId>enforcer-‐api</artifactId> <version>${api.version}</version>
</dependency> <dependency>
<groupId>org.apache.maven</groupId> <artifactId>maven-‐project</artifactId> <version>${maven.version}</version>
</dependency> <dependency>
<groupId>org.apache.maven</groupId> <artifactId>maven-‐artifact</artifactId> <version>${maven.version}</version>
</dependency> <dependency>
<groupId>org.apache.maven</groupId> <artifactId>maven-‐plugin-‐api</artifactId> <version>${maven.version}</version>
</dependency>
Enforcer API
Maven integration
By: Lennart Jörelid
Execution entry point
/** * This is the interface into the rule. This method should throw an exception * containing a reason message if the rule fails the check. The plugin will * then decide based on the fail flag if it should stop or just log the * message as a warning. * * @param helper The helper provides access to the log, MavenSession and has * helpers to get common components. It is also able to lookup components * by class name. * * @throws EnforcerRuleException the enforcer rule exception */ void execute( EnforcerRuleHelper helper ) throws EnforcerRuleException;
By: Lennart Jörelid
public final void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
// Acquire some Maven object from Maven expressions MavenProject project = (MavenProject) helper.evaluate("${project}"); MavenSession session = (MavenSession) helper.evaluate("${session}”); String target = (String) helper.evaluate("${project.build.directory}”); String artifactId = (String) helper.evaluate("${project.artifactId}”);
…
POM Maven3 variables
By: Lennart Jörelid
/** * Delegate method, implemented by concrete subclasses. … * @throws RuleFailureException If the enforcer rule was not satisfied. */ @Override protected void performValidation(
final MavenProject project, final EnforcerRuleHelper helper) throws RuleFailureException {
try { ProjectType.getProjectType(project); } catch (IllegalArgumentException e) { throw new RuleFailureException(e.getMessage()); }
}
Yay! The criterion!
By: Lennart Jörelid
Enum with all known project
types
Pattern matching to define type
Factory method
By: Lennart Jörelid
Plugin Conbiguration & rules debinitions
Checkstyle.xml Checkstyle conbiguration document
Learning more Checkstyle site
By: Lennart Jörelid
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-‐checkstyle-‐plugin</artifactId> <version>${checkstyle.plugin.version}</version> <dependencies> <dependency> <groupId>se.jguru.foundation.tools</groupId> <artifactId>codestyle</artifactId> <version>${tools.codestyle.version}</version> </dependency> </dependencies> <configuration> <configLocation>codestyle/checkstyle.xml</configLocation> <failOnViolation>true</failOnViolation> <violationSeverity>error</violationSeverity> </configuration>
</plugin>
Codestyle project
Checkstyle configuration
By: Lennart Jörelid
Checkstyle configuration
By: Lennart Jörelid
<?xml version="1.0" encoding="UTF-‐8"?> <!DOCTYPE module PUBLIC "-‐//Puppy Crawl//DTD Check Configuration 1.3//EN”
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> <module name="Checker"> <property name="severity" value="warning"/> <module name="TreeWalker">
-‐-‐-‐ rules -‐-‐-‐
<!-‐-‐ We should not use Calendar or Date types in any public method. They could be used internally -‐ and only within model classes to cope with JPA time types – but not within parameters or return types.
-‐-‐> <module name="IllegalType">
<property name="severity" value="error"/> <property name="tokens" value="PARAMETER_DEF, METHOD_DEF"/> <property name="illegalClassNames” value="java.util.GregorianCalendar, java.util.Calendar, java.util.Date, java.util.Vector"/>
</module>
Breaks the build!
By: Lennart Jörelid
Plugin Conbiguration & coverage debinitions
Reports Understanding cobertura reports
By: Lennart Jörelid
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>cobertura-‐maven-‐plugin</artifactId> <version>${cobertura.plugin.version}</version> <configuration> <instrumentation> <includes> <include>se/jguru/foo/**/*.class</include> </includes> <excludes> <exclude>se/jguru/**/*Exception.class</exclude> <exclude>se/jguru/generated/**/*.class</exclude> </excludes> </instrumentation> <check> <branchRate>65</branchRate> <lineRate>80</lineRate> <haltOnFailure>true</haltOnFailure> </check> </configuration>
</plugin>
Control excludes
Rates
By: Lennart Jörelid
”Line Coverage” % lines in release code executed by unit tests
”Branch Coverage” % branches in release code executed by unit tests
… ”branch” == possible execution path …
By: Lennart Jörelid
¡ Generated in the build process § mvn site
¡ Find reports in target/site § Simply open with a web browser
By: Lennart Jörelid
By: Lennart Jörelid
16 times covered
93 % coverage
Unit test coverage
miss
Unnecessary code? Insufficient tests?
By: Lennart Jörelid
What is ”Conditional coverage”?
By: Lennart Jörelid
¡ Enforces the development handbook § Ensures that no project shortcuts can be taken
¡ Enforced using maven-‐enforcer plugin § … and checkstyle as well § Uses your custom rules to feed the enforcer
By: Lennart Jörelid
¡ Efbicient projects need appropriate design § Reducing the need for excessive documentation improves ratio of productive to waste time
¡ Automatic validation of projects, code and dependencies improve usability § Use appropriate plugins to implement enforcement
¡ FOSS sample provided …
By: Lennart Jörelid
PoC provided – clone, use and
give me feedback
http://bitbucket.org/lennartj/nazgul_tools http://bitbucket.org/lennartj/nazgul_core
By: Lennart Jörelid
Any questions?
4: Q & A
By: Lennart Jörelid
Thank you for attending