refactoring application express - amazon web...
TRANSCRIPT
2
Refactoring Application
Express
• “Too often the design is determined by the
first way everyone agrees it would work” Refactoring SQL Applications, Stéphan Faroult
3
Refactoring Application
Express • What is Refactoring
• Refactoring Goals and Focus Areas
• APEX Focus Areas for Refactoring
• Finding What to Refactor
• Strategies and Challenges
• Process Overview
• Example Refactorings
4
What is Refactoring
• Stepwise Refinement
• Not just tuning
• Not intended to provide new functionality
BUT
• It can lay groundwork for new functionality
• Evolution = Adapt or Die
“An effective architecture is one in which the most
likely changes are also the easiest to make.”
Software architecture in practice, Len Bass
5
What is Refactoring in APEX • In APEX code is organized within a
framework
• Rewriting code goes hand in hand with
reorganizing the application
• APEX architecture informs choices
6
If it ain’t broke…Why
Refactor Immediate Needs
• Security
• Performance
• Simplify
maintenance
• Scalability
• Data integrity
Future Goals
• Extend functionality
• UI Changes – AJAX ~80% of effort in systems occurs after
deployment
7
Refactoring Goals
• Simplify
• Enhance performance
• Take advantage of new features
• Enhance security
• Scalability
• Reusability – Decoupling
• Specific vs. Generic
8
Coding Practice Goals
• Reduce
– Redundant Code
– Dynamic SQL
– HTML in SQL and PL/SQL
• Small Code Units
• Stored Object Names
• SPODIFICATION
• Adopt a Meta Data Mindset
9
Goals and Strategies
Goal Strategy
Performance Inter-element Communication
Modifiability Element Responsibilities
Security Inter-Element Communication
Scalability Localization of Resources
Ability to Subset Inter-Element Usage
Reusability Inter-Element Coupling Source: Carnegie Mellon Software Engineering Institute
10
Simplification
Look for opportunities to SPODIFY
• Conditions
• Application Items
• Application Computations
• Application Processes
• Report SQL
11
Performance
• Caching
– Region Cache
– SQL Cache Hint (11g)
– Function Result Cache (11g)
• Statement Tuning
12
Take Advantage of New
Features Take advantage of new features in APEX
• WWV_FLOW_ASSERT
• APEX_UTIL.JSON_FROM_XX
• JavaScript APIs (apex_ns_3_1.js)
Prepare for new features in Application
• Data Access Layer API
• Application Processes
14
Scalability Closely related to performance
• Localization of Resources
• Session State Data
• PPR/Cascading LOVs
• Use of Static Files
– one big file vs several smaller ones
– store static files outside of DB
• Reduce Network Trips
• Reduce Individual DB Reads
15
Reusability
Decoupling
• Stored predicates
• Rules Manager/Expression Filter
• Queues and Jobs
• APIs encapsulating tables
• Web Services
• Workflow
• AJAX – URI dependence
17
Specific vs. Generic
• Generalization
– Adds flexibility
– Increases centralization
• Specificity
– Can enhance performance
– Can ease troubleshooting
18
Refactoring APEX
How can refactoring be applied to APEX?
• Examine APEX architecture
• Look for crossover functionality
• Look for opportunities to SPODIFY
20
Refactoring APEX
• Explore the Architecture
• Look for crossover functionality
• Use APEX views and application
reports
• Look for side effects
• Consider page lifecycle
21
APEX Refactorings
• Items – Page, App, Temp
• Conditions
• Processes – Auto vs. PL/SQL
• Validations
• Branches
• Computations
23
APEX Refactorings
• Items – Page, App, Temporary
– Replacing page items with
Application Items
– Replacing page items in AJAX calls
with temporary items
• addGlobals()
24
APEX Refactorings
Conditions
• Conditions are everywhere
• Perfect for centralizing with boolean
functions
25
APEX Refactorings
Processes – Auto vs. PL/SQL
• Automatic DML and Row Fetch
– Very flexible
– Built-in optimistic locking
– Item to column mapping
– Lacks logging
– No control over errors
– Auto row fetched data not persisted* *http://c2anton.blogspot.com/2008/12/oracle-application-express-apex-three.html
26
APEX Refactorings
Validations
• Ordering and short circuiting
• Reduce redundancy
• Not much crossover
• Extract logic into computation
27
APEX Refactorings
Branches
• Use of ITEM vs Page number
– App Level Item vs Page Level
• New set session state option
• Ordering and short circuiting
28
APEX Refactorings
Computations
• Reduce redundancy with a process
• Combine calls to the same table
– Set values in a process
29
APEX Refactorings
Reports
• Replace dynamic SQL source
• Move HTML to column attributes and templates
• Simplify SQL with DB view
• Reusable predicates
• SQL calculated attributes
• APEX_COLLECTION
30
APEX Refactorings
Regions
• HTP vs. Template
• Go beyond HTP.P
– Htp.anchor
– Htp.tablexxx
• APEX_ITEM – Updatable Report
• Translatable text
31
APEX Refactorings
JavaScript – AJAX
• $ functions
• apex.ajax.ondemand
• AddArrayItems()
• AddPageItems()
• APEX_UTIL.JSON_FROM_SQL
• $d_LOV_from_JSON
32
AJAX – URL Decoupling $a_report() - APEX PPR
pagination and
sorting function var l_URL =
'p='+$v('pFlowId')+':'+$v('pFlowStepId')+':'+$v('pInstance')+':FLOW_PPR_OUTPUT_R'+pId+'_';
… var ajax = new
htmldb_Get(null,null,null,null,null,'f',l_URL);
var gReturn = ajax.get();
f?p wwv_flow.show
App p_flow_id
Page p_flow_step_id
Session p_instance
Request p_request
Debug p_debug
Clear Cache p_clear_cache
Item Names p_arg_names
Item Values p_arg_values
PrinterFriendly p_printer_friendly
34
Finding What to Refactor
• Beauty of APEX is the metadata
• APEX Component Reports
• APEX Views
• Object Dependencies
• Page “Referenced” View
35
Finding What to Refactor
Hack the Object Depenendencies
Report
APEX_030200.wwv_flow_theme_files.find_obj
ect_dependencies
(p_flow_id=>:P1_APP_ID, p_page_id=>null);
• Need to grant rights to package
36
Finding What to Refactor
select SEQ_ID AS ORDER_SEQ
, C001 AS schema_name
, C002 AS object_name
, C003 AS object_type
, C004 AS component_name
, C005 AS page_number
, C006 AS component_id
, C007 AS component_source
, C008 AS app_id
, C009 AS bound_items
, C010 AS component_type
, C011 AS component_source_type
from htmldb_collections
where c008 = :P1_APP_ID
and c002 <> 'PLITBLM'
and collection_name = 'ALL_DEPENDENCIES'
38
Strategies
• Decide goals
• Determine scope
• Choose methods
• Create plan
• Test
• Document
• Release
39
Strategies
Important Considerations
• System owner needs
• System owner capabilities
• Future changes and growth
• System owner buy in
“Every design decision comes down to cost,
benefit, and risk” The Data Model Resource Book - Volume 3, Len Silverston
40
Strategies
System Owner Considerations
• Capabilities and capacity
• Complexity of resultant architecture
• Maintenance of resultant system
• Administration of resultant system
New processes, scheduled jobs
• Exception reporting
41
Strategies
Future changes and growth
• How far do you go in anticipating the
progression of needs
• Does the system require more or less
flexibility in design
• Consider reusing or integrating subsets
42
Strategies
Getting Buy In
• Original developer objections
• Time vs. Benefit
• Low Hanging Fruit
• Don’t estimate performance gains
• Prove inefficiencies
43
Strategies
• Smaller changes are easier
• Break your work into smaller tasks
• Determine scope of changes
• The greater the coupling the harder the
refactoring
• Track changes carefully
44
Strategies
Measuring your work
• How will you measure progress?
• What metrics go with your goals?
• Can you build instrumentation from your
analysis tools?
45
Process Overview
• Determine refactoring(s) needed
• Choose the method(s)
• Determine the scope
• Create a new version with changes
• Test
• Document
• Release
46
Example Refactorings
Add a column to the database
• Add column to db
• Add item to page
• Set the db column attributes - Auto Fetch
and Auto DML
• OR
• Add column to fetch or calculation
• Add column to DML process
47
Example Refactorings
Replace SQL Exists condition with function
• SQL Conditions might seem innocuous in
the beginning but once your data grows
you might begin to see a performance hit
• If this filtered on an un-indexed column or
it includes a function call performance can
suffer
• Conditionals are often redundant
48
Example Refactorings
Replace condition with authorization scheme
• If the condition relies on user dependent
attributes alone it is a good candidate for
an authorization scheme
• Probably an even better candidate for a
stored function
• An even better candidate for 11g Function
Result Cache
49
Example Refactorings
Replace page process with on demand
application process
• May entail the creation of app items
• New app items need to have values set
• Extends possibilities for using AJAX
50
Example Refactorings
Replace multiple branches with process to
set target page and branch to it
• May reduce redundant calls to functions
within branch conditions
• Good way to reduce function and/or query
based conditions
• Puts page branch logic in one block
• Eliminates the problem of a branch
reordering causing unexpected results
51
Example Refactorings Replace Dynamic SQL with Static SQL
• Variable column lists can be made
conditional in the report attributes
• Variable table lists might indicate a bigger
problem with your design
52
Example Refactorings Replace Dynamic SQL with Static SQL
• Consider the use of CASE for nested conditionals
• Think beyond “this column equals that”
• Case construct allows nested conditions –
if this is true then check these other things
• Put null conditions first to take advantage
of short-circuit evaluation
• Order conditions from most to least true
53
Example Refactorings Example using CASE for where conditions SELECT *
FROM my_table
WHERE 1 = CASE
WHEN :G_SEC_LEV < 3 AND :G_FACILITY_ID = 0 THEN
CASE WHEN region_id = :G_REGION_ID THEN 1
ELSE 0 END
WHEN :G_SEC_LEV < 3 AND :G_FACILITY_ID != 0 THEN
CASE WHEN facility_id = :G_FACILITY_ID THEN 1
ELSE 0 END
WHEN :P69_REGION_ID != 0 THEN
CASE WHEN region_id = :G_REGION_ID THEN 1
ELSE 0 END
ELSE 1
END
54
Example Refactorings Example using CASE for columns SELECT CASE
WHEN INSTR(':' || sec_lev || ':'
, ':' || :G_SEC_LEV || ':')>0
THEN
CASE WHEN next_sec_lev IS NOT NULL
THEN
'<a href="#" onClick="push(' || g.grid ||
'); return false;">PUSH</a>'
WHEN next_sec_lev IS NULL
THEN
'<a
href="f?p=&APP_ID.:71:&APP_SESSION.:::71:P71_GRID:
' || g.grid || '">Submit</a>'
END AS push_link
55
Example Refactorings CASE statement constructs
Given mutually exclusive conditions a-d within 100 records
The ordering of the evaluation affects the total number of evaluations
CONDITION TRUE FALSE # EVALS
a 10 90 100
b 20 80 90
c 30 70 70
d 40 60 40
total records -> 100 300
CONDITION TRUE FALSE # EVALS
d 40 60 100
c 30 70 60
b 20 80 30
a 10 90 10
total records -> 100 200
56
Example Refactorings Replace Automated Row Fetch with PL/SQL
expression
• Automated Row Fetch doesn’t persist session state
• No data is not an error
• Consider using record types FUNCTION get_emp(empid IN NUMBER)
RETURN employee%ROWTYPE;
DECLARE
emp_rec employee%ROWTYPE;
BEGIN
emp_rec := get_emp(:PX_EMPID);
:PX_emp_lname := emp_rec.lname;
57
Example Refactorings Replace Automatic DML with PL/SQL
• Allows for custom error handling
• Consider (again) using record types PROCEDURE update_emp(empid IN employee%ROWTYPE);
DECLARE
emp_rec employee%ROWTYPE;
BEGIN
emp_rec.emp_id : = :PX_EMPID;
emp_rec.lname := :PX_EMP_LNAME;
…
update_emp(emp_rec);
58
Example Refactorings
Rewriting Conditions
• Conditions are everywhere
• Reduce redundancy
• Reduce use of session state (items)
• May need to find PL/SQL equivalents for
unique condition types
– Current Page = Page Submitted
59
Example Refactorings
• APEX_APPLICATION_PAGE_VAL
• APEX_APPLICATION_PARENT_TABS
• APEX_APPLICATION_PROCESSES
• APEX_APPLICATION_SHORTCUTS
• APEX_APPLICATION_TABS
• WWV_FLOW_LIST_ITEMS
• WWV_FLOW_MENU_OPTIONS
• WWV_FLOW_PAGE_PLUGS
• WWV_FLOW_REGION_REPORT_COLUMN
• WWV_FLOW_REGION_REPORT_FILTER
• WWV_FLOW_STEPS (Cache condition)
• WWV_FLOW_STEP_BRANCHES
• WWV_FLOW_STEP_BUTTONS
• WWV_FLOW_STEP_VALIDATIONS
• WWV_FLOW_TABS
• WWV_FLOW_TOPLEVEL_TABS
• APEX_APPLICATION_BC_ENTRIES
• APEX_APPLICATION_COMPUTATIONS
• APEX_APPLICATION_LIST_ENTRIES
• APEX_APPLICATION_LOV_ENTRIES
• APEX_APPLICATION_NAV_BAR
• APEX_APPLICATION_PAGES
• APEX_APPLICATION_PAGE_BRANCHES
• APEX_APPLICATION_PAGE_BUTTONS
• APEX_APPLICATION_PAGE_COMP
• APEX_APPLICATION_PAGE_IR
• APEX_APPLICATION_PAGE_IR_COL
• APEX_APPLICATION_PAGE_IR_COND
• APEX_APPLICATION_PAGE_ITEMS
• APEX_APPLICATION_PAGE_PROC
• APEX_APPLICATION_PAGE_REGIONS
• APEX_APPLICATION_PAGE_RPT_COLS
Conditions are everywhere
60
Example Refactorings
Replacing Conditions with Authorizations
• Can be evaluated per session or page view
• Can be subscribed to for sharing across
applications
• Can be reused in Conditions apex_util.public_check_authorization
(‘AUTHORIZATION_SCHEME_NAME’)
• Can be reset as needed (all or nothing) apex_util.reset_authorizations
61
Example Refactorings
Replacing Conditions with Authorizations • Available for the following components
– Application
– Computation
– Navigation Bar
– List Items
– Breadcrumb Entry
– Region
– Process (page and app level)
– Report Column
– Page
– Branch
– Button
– Item
– Validation
– Tab
62
Example Refactorings
Replacing Item Level LOV with shared LOV
• WWV_FLOW_STEP_ITEMS.LOV
Shows LOVs defined at item level
63
Suggested Reading
Refactoring Databases:
Evolutionary Database
Design
Scott W. Ambler and
Pramodkumar J. Sadalage