
8f9d4ee9cb7b91b08cd5b780ce0826b1.ppt
- Количество слайдов: 117
NAAM ADF Development More tales from the trenches Aino Andriessen AMIS Services
• • • Systems integrator Co-sourcing Maintenance Oracle, Java, Open Source, ADF, DBA, SOA AMIS technology school Pagoni • http: //www. amis. nl • http: //technology. amis. nl/blog/
Aino Andriessen • • Technical Consultant Technical Architect Java, ADF, PL/SQL, XML, . . . SOA , Integration Software engineering Quality management Agile development • aino. andriessen@amis. nl • http: //www. fttech. net
Let's build an ADF application to. . .
experience the development process and. . .
to build better ADF applications. . .
Stakeholders customer developer maintenance project lead
better according to. . . Customer Fully functional Within budget On time
better according to. . . Project lead Within budget Functional Big
better according to. . . Developer Organized Fully Featured Stable
better according to. . . Maintenance Easy to maintain Stable Secure
better according to. . . Girlfriend Not being late Happy Still have some energy left
• How can we make better ADF applications?
Knowledge creates good software A professional attitude creates better software
5 essentials • • • Communication Responsibility Knowledge Organization Fun
• Let's start coding. . .
• Sorry, not yet. . .
Organization. . . • • • Project Development process Skills Project structure (file structure) Code Design and Architecture Documentation Communication Infrastructure
Software factory
A software factory is a professional way of working supported by tools
Source control Tests Developer 2 Inspection Documentation site Reports Documentation Custom Corporate Library Build automation Issue reports Delivery environments Library Public Library Production Acceptance Test Issue management Integration Development
• Can we now start coding?
• Almost. . .
Development principles
Focus on functionality
Refactor without fear
• OK, wake up and let's get to business. . . Demo time. . .
• Build an ADF - JHeadstart application • Address common and not so common issues • ADF 10 g – Some 11 g
Demo • Regatta Management System • Application to support sailing regatta's. – maintain regatta's – registration – enter racing data – results
Development Goal • Match implementation against stakeholders' concerns : – Functional – Maintainable – Stable – Budget – Organized – Fun –. . .
Business Logic
Business Logic implementation • Business Logic can be implemented at many locations – ADF Faces components • • Managed beans Backing beans EL-expressions Attributes – Service methods – VO's • Attributes : transient, calculated • Methods – Entities • Attributes • Validators – Database • Constraints • Views • Stored procedures –. . .
The (ADF) challenge • Consistent and comprehensible implementation of business logic.
FD • Requirements – – Maintain regatta information Allow sailors / boats to enter a regatta. • – – – • Register skipper and captain (owner) with some personal details Schedule racings Easy registration of race details, only by certain people Publish results Nice look and feel Easy to use Handle handicap system Business rules – – – Participant, skipper, must be older than 18 Same boat may enter only once Finishtime after starttime Participant can have only one result It should be able to reset the finish of a participants, in case of error Register if the boat didn't start or finish, using the common codes like DNF, DNS, DSQ etc. • – Extra information about this situation must be entered Races cannot be scheduled at the same time
Functions / Use cases • • • Maintain regatta's Register for a regatta Enter racing data Publish results Supportive functions
Design and Architecture
ADF 'architecture' • ADF applications tend to evolve instead of being designed. – Viewobjects are created when needed – Managed beans are created as needed – Application Modules function merely as a service-hatch • ADF doesn't force you into an organized application, except maybe the model and view. Controller. • ADF offers multiple solutions for the same problem and in the end all of them will eventually appear in the application. JBF
ADF architecture ADF Faces ADF model (binding) ADF BC Database
ADF architecture ADF Faces Managed beans ADF model (binding) ADF BC Objects Application Modules View. Objects Entities Database Stored Procedures Tables Views
Application Integration ADF Application Webser vices Files Database Notifica tion Messa ging
Service Architecture
Function / Use Case approach • The application module, the service, is the core of the application • Each function / use case is implemented as a service. • Services can be nested
ADF architecture ADF Faces Webser vices ADF model (binding) Service ADF BC Webser vices Service Files Database Service Notifica tion Service Messa ging
RMS Services
Datamodel
Datamodel
Datamodel 2 • Views – 1 : 1 on tables : vpd, – complex queries • Stored procedures • app_owner and app_user
Development
Development environment • • • JDeveloper 10 g 10. 1. 3. 4 JHeadstart 10 g 10. 1. 3. 3 Oracle 11 g R 1 OC 4 J 10. 1. 3. 4 Maven 2. 1 Subversion 1. 5
JDeveloper Setup • External tools • Encoding UTF-8 – Preferences -> Environment • Upgrade JDev svn client to 1. 5 – http: //technology. amis. nl/blog/5253/upgrade-jdeveloper 10 g-subversion-client
JDeveloper • Organize imports • Define. vm as text file – preferences -> filetypes • Default editors : source – preferences -> filetypes
Project setup
Projects common database deployment ear model view. Controller lib General code, Baseclasses Reusable's Database code, scripts (automated) Deploy to i. AS Build deliverable, ear ADF BC's UI ADF Faces 'External' libraries
Maven conventions - code
Maven conventions - unittests
Don't re-invent the wheel
General • • SRDemo JHeadstart framework Weblogs Documentation – Developer’s Guide Forms/4 GL Developers • Simple Emp reference project
BC Creation
Default - create BC's from table
Default - create BC's from table
BC creation 1. 2. 3. 4. 5. 6. Services Entities Associations Viewobjects Viewlinks VO usages • Apply naming conventions – Refactor if needed • Organize, organize
Create Entities • Create Business components from table – Refactor associations • Base on table, change later to database view
Edit entities • Set Id from sequence – DBSequence is a nightmare to refactor • Control Hints – Enter once, use often
Associations • Association properties – apply correct plural and singular • Define Composition Association – Developer’s Guide Forms/4 GL Developers - Chapter 6. 3. 3
Business rules BR Implementation Participant, skipper, must be older than 18 Entity validation Same boat may enter only once Unique key Finishtime after starttime FE or DB or 'complex' entity Participant can have only one result Unique key It should be able to reset the finish of a participants, in case of error FE function Register if the boat didn't start or finish, using the common codes like DNF, DNS, DSQ etc. Datamodel, domain Extra information about this situation must be entered FE, mandatory dependency Races cannot be scheduled at the same time Unique key? A boat either has a finishtime or a special situation Row validation
Entity Business Rules • Mandatory, PK, UK • Validation – Declarative – Method – Rules • Declare in project properties – Very Reusable • [Entity constraint] – NO validation – Only present for creating table from entity
Validators / Rules • Create Registered Rule in project properties – Or reuse an existing one • Implement code in validate. Value method
Validators • Select the Rule as attribute validation • Test
Entity Validation - remarks • The setter immediate triggers the validation – actually the set. Attribute. Internal(. . . ) • Validations are executed top to bottom • Row validation is performed 'independent' of attribute validation. • Declarative Date validators are limited – Use Validators • Using a select statement for validation is very limited (if it works at all) – Avoid it. • Consider Validator when the same validation is entered multiple times. • Validator exception msg not published to the front-end (as we'll see later)
(J)Unittesting Entities • Create Application Module : import oracle. jbo. client. Configuration; Registration. Service. Impl _am; public void set. Up() { _am = Configuration. create. Root. Application. Module ("nl. amis. demo. rms. model. services. Registration. Service" , "Registration. Service. Local. URL "); } public void tear. Down () { Configuration. release. Root. Application. Module(_am, true); } • Create entity : Entity. Def. Impl empdef = (Entity. Def. Impl)Entity. Def. Impl. find. Def. Object ("nl. amis. demo. rms. model. entities. Crew. Member"); crew. Member = (Crew. Member. Impl)empdef. create. Instance 2 (_am. get. DBTransaction(), null);
• Execute test : Date test. Date = (Date)Date. get. Current. Date(); try { crew. Member. set. Birthdate(test. Date); fail(); } catch (Exception e) { e. print. Stack. Trace(); } test. Date = (Date)test. Date. add. Months(-12*20); try { crew. Member. set. Birthdate(test. Date); } catch (Exception e) { fail(); e. print. Stack. Trace(); }
Unit-testing ↑ code control ↑ code quality ↓ development time • • • 'Automatic' regression test TDD improves the testability of your code Unit-testing increases your ADF skills Easy debugging of BC's Automated execution at continuous integration
Unittest framework • Test. Base per application module – provide Service. Impl • Utility methods – Create entity • Standardization – Authorization – Context
I don't write unittests because it takes too much time I'll start the application, login, navigate to the right screen and then perform the correct actions? Then, how do you test your code? Gee, How long does that take?
VO Remarks • Often screen, Use Case driven • Organize – the number may increase rapidly – Separate list-only VO's • Apply naming conventions – – plural Lkp Trnsnt. . . By. . . • Don't use 'automatic BC creation from database' – Unless you like refactoring. . .
VO remarks • Calculated attributes are not updated automatically, but need a requery – This may often result in complex code
Domain driven logic • No. Finish. Code – DSQ, DNF, DNS • define constants or enum • Is. XXX attributes
VO client interface methods • Implement VO related functions – start. Race() – disqualify. Participant() –. . • Maybe also published as Service interface method • Beware with nested applicationmodules to bind the correct method – or else the get. Current. Row does not work – NB, bindings work ok
Bindings and Nested AM
Viewobject validation • Override validate() method • setter method • throw Jbo. Exception – define your own
View object usages • Naming conventions • Organize them in services
Unittesting VO's (Usages) • Basic test – execute. Query • Business Logic • Beware of detail VO's – they are direct available on the AM, but relate to their parent
Programmatic viewobjects • e. g. for Webservice clients • See Developer’s Guide Forms/4 GL Developers Chapter 9 • Jhs. Programmatic. View. Object – get. Jhs. Programmatic. Result. Set • ! Executed many times – Override execute. Query() to actually retrieve data – Store result in Jhs. Programmatic. Result. Set class variable – Convert using Jhs. Programmatic. Helper. convert. Bean • Match attributes with ws return object
Re-use • • • Bases classes Validators Unittest utilities Date handling ADF Binding (model) methods – SRDemo : JSFUtils and ADFUtils • • JHeadstart templates Business Components Task flows Beans Converters Filters. . .
Organize Re-use • Separate projects, libraries, and owners • Review / audit criteria
Reuse BC's • • Separate project Create deliverable Add jar to project Import jar • Beware, sharing database connection from root application module
Refactor without fear
Refactoring BC's • http: //technology. amis. nl/blog/2859/fear-forrenaming-refactoring-adf-bc-objects-injdeveloper-is-not-unfounded • Renaming and moving BC's is handled quite well. • Bindings are not automatically adjusted • JHeadstart is not automatically updated – Generation errors – Just reselect the attribute / group • Try to be strongly typed
Refactoring remarks • Matching subversion clients • Refactoring DBSequence attributes is a pain. . . • ADF does not always allow you to refactor, in case of dependencies. • Validator – Re-registration of the Rule • Beware of static 'dependencies' in the JHeadstart templates
JHeadstart • One application definition vs. multiple – Can merge and split quite easily – 11 g support for multiple improved • JHeadstart supports nested application modules • Apply standards and naming conventions • Configuration – tools -> preferences • e. g. item prompt – App. Def root node • AM superclass
Custom Templates • Application hierarchy matches the default • Documentation of templates • Try to avoid hard-coded bindings – difficult to refactor – custom properties • Buttons can be generated – however, the binding is not
Common recommendations • Understand the framework • Avoid 'bindings', use a managed bean and dependencies • Custom bindings : Disable 'Clear Page Definition' • Close pagedefs before generation
Date and time • Using Java Date and Calendar and oracle. jbo. domain. Date and Timestamp can be tricky – new oracle. jbo. domain. Date() ? – new oracle. jbo. domain. Timestamp() ? – Date. get. Current. Date() ? – ((Date)Date. get. Current. Date()). timestamp. Value • actually java. sql. Timestamp • Current time?
Date and time - Calendar c = Calendar. get. Instance(); oracle. jbo. domain. Timestamp ts = new Timestamp(c. get. Time()); Timestamp ts = new Timestamp(c. get. Time. In. Millis()); c. set(Calendar. HOUR_OF_DAY, 5)
Date Time - Joda. Time Date. Time dt = new Date. Time(); Timestamp ts = new Timestamp(dt. get. Millis()); Date. Time dt=new Da dt. get. Hour. Of. Day(); dt. plus. Minutes(10); dt. minus. Weeks(5); dt. is. After(dt 2); dt. is. Before. Now(); te. Time(2009, 6, 14, 13, 0, 0, 0)
Search Programmatic viewobject • Standard JHeadstart Search – Allows searching using the VO attributes – Creates 'SQL formatted' View. Criteria • oracle. jheadstart. model. Query. Condition • unusable for Programmatic viewobject 1. Somehow retrieve actual data from viewcriteria 1. Strip the formatting 2. Provide the actual value 1. e. g. via the oracle. jheadstart. model. Query. Condition 2. Override Jhs. Application. Module. Impl. advanced. Search()
Store search criteria • On login requery the latest search • Extend Jhs. Search. Bean • Override advanced. Search() – Serialize the criteria to file – Use the user. Id as name for the file • Constructor – Retrieve the criteria from file
Design first
• http: //groups. google. com/group/adfmethodology