Design Patterns Every ISV Needs to Know (October 15, 2014)
-
Upload
salesforce-partners -
Category
Technology
-
view
126 -
download
4
description
Transcript of Design Patterns Every ISV Needs to Know (October 15, 2014)
Design Patterns Every ISV Needs to Know
Andrey Volosevich Senior ISV Technical Evangelist salesforce.com @andreyvol
Mac Anderson CTO, Fonteva @macscloud
Ross Belmont Chief of UX, Appiphony @rossbelmont
Safe Harbor Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with completed and any possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year and in our quarterly report on Form 10-Q for the most recent fiscal quarter. These documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
Agenda: Design Patterns Every ISV Needs to Know
• Top Pattern in 2014: Enforcing Data Access in Apex
• Configuration Patterns for Testing and Flexibility
• Architecting Large Apps using Dependency Injection Principles
• Q & A
“I wish we had done this earlier…”
Top Pattern in 2014 Enforcing Data Access in Apex Andrey Volosevich, salesforce.com Senior ISV Technical Evangelist
CRUD/FLS Enforcement: Example
[Select Name, Net_Worth__c from Investor__c Where Id = :xxx];
CRUD/FLS Enforcement: Example
CRUD/FLS Enforcement: Example
[Select Name, Net_Worth__c from Investor__c Where Id = :xxx];
Your app is not respecting my Data Security Policy???!!! What?!
CRUD/FLS Enforcement
FLS Field Level Access
CRUD Object Level Access
Record Sharing
CRUD/FLS Enforcement
FLS Field Level Access
CRUD Object Level Access
Record Sharing
CRUD/FLS Enforcement
FLS Field Level Access
CRUD Object Level Access
Record Sharing
Apex does not enforce Object and Field level access. Visualforce does enforce but only for Concrete SObject Bindings
FLS Enforced: <apex:outputField value=”{!Investor__c.NetWorth__c}”/> FLS Not Enforced: <apex:outputText value=”{!getNetWorth}”/>
CRUD/FLS Enforcement: Schema Reflection
• Use Reflection
C R U D
Field access implicitly checks for object access, no need to check both
• Checking access for multiple fields dynamically
CRUD/FLS Enforcement: Checking at Runtime
Keep mind, there are no more limits on # of Schema describe statements
CRUD/FLS Enforcement – Encapsulate, Use Libraries • Don’t Repeat Yourself!! Abstract away complexity, avoid duplication, keep business logic clean
force-dot-com-esapi also does input validation and output encoding http://p.force.com/esapi
CRUD/FLS Enforcement • Write unit tests for different User Profiles – runAs()
CRUD/FLS Enforcement • Write unit tests for different User Profiles – runAs() • Build secure coding and good design practices in your team’s DNA
CRUD/FLS Enforcement • Write unit tests for different User Profiles – runAs() • Build secure coding and good design practices in your team’s DNA • Platform gives your customer control – do not take it away.
CRUD/FLS Enforcement • Write unit tests for different User Profiles – runAs() • Build secure coding and good design practices in your team’s DNA • Platform gives your customer control – do not take it away. • Be kind to your future self!
OK, this is helpful. But I have a complex app, what else you got?
Beyond CRUD/FLS: Community Lib fflib-apex-common • Example: QueryFactory
Other Enterprise Patterns: Service Layer, Selector Layer, Domain Layer, Apex Mocks https://github.com/financialforcedev/fflib-apex-common
Place Customer or
Partner logo in white area of
slide, centered horizontally
Ross Belmont Design Patterns for Flexibility Chief of UX, Appiphony @rossbelmont
Two Examples • Secure testing of external web services • Importing a diverse data set while architecting for flexibility
First Example
Different Endpoint for Testing
How Will the App Know the “Right” Endpoint?
Custom Code Populates a Protected Custom Setting
“Testing Flag” Alters the Custom Code’s Behavior
Benefits of This Approach • The app references the correct endpoint at the correct time • Only you (as the ISV) can specify the external endpoint
– If customers configured it themselves, there would be a support burden – No one can set the endpoint maliciously for a “man in the middle” attack
• Swapping the endpoints is simple (just install the extension package) • The extra “testing flag” object doesn’t pollute customer environments
Use to introduce a
demo, video, Q&A, etc. Importing a Diverse Data Set
Architecting for flexibility to serve a broader customer base
External Web Service Creates a “Dossier”
• Creates different marketing campaigns targeted at alumni of specific universities
Different Types of Customers
• Drives marketing based on traditional demographic segmentation – Age – Gender
Contact and Dossier: Objects in the Org
Contact Looks Up to Dossier
Subscriber A Can Report on Age, Gender
Subscriber B Can Focus on Alumni Instead
Benefits of This Approach • Customers can add exactly what they want to the Contact record and layout, and nothing more
• Reporting is simplified by flattening down to the Contact record • A Dossier can be attached to Leads, etc. in the future • Easy to serve new marketing initiatives in the future
– Recent grads vs. 20 year alumni, for example (incorporating Age)
Place Customer or
Partner logo in white area of
slide, centered horizontally
Mac Anderson CTO, Fonteva
The Challenges of Building Software in the Cloud
• Upgrading customers • Compatibility with customer environment configurations
– Other managed packages – Salesforce.com features (Person Accounts, State + Country Picklists, etc…) – Misc. customer built workflows and triggers
• Package Bloat • Force.com Governor Limit compliance
3 Common Pitfalls to Avoid
• Don’t build a killer demo app unless you like big balls of mud • Never say “Our customer’s won’t do that…” with your code • Solve the same problem the same way all the time
Loosely Coupled Systems Put ISV’s in the Driver Seat • Organized as a web of modular, interacting objects • Cohesive with little to no dependencies • Flexible • Consistent
A simple concrete example
Feature: “Allow customers to process credit card payments online for orders managed in our app.”
A simple, but flawed approach
public class PaymentService {!! public PaymentResult processPayment(CustomerOrder order) {! PaypalService paypal = new PaypalService();! PaymentResult = paypal.processPayment(order);! return result;! }!!}!
Success! You can process payments… But what happens when…
• You sell your app to a customer in the UK where PayPal does not support Direct Debits?
• Your biggest prospect is Stripe : ) • Your customers are demanding support for another vendor where they get a better rate?
The implementation re-factored !public class PaymentService {!! public PaymentResult processPayment(CustomerOrder order, PaymentProcessor vendor) {! PaymentResult result = new PaymentResult();! if (vendor.name == 'PayPal') {! PaypalService paypal = new PaypalService();! return paypal.processPayment(order);! } else if (vendor.name == 'Stripe') {! StripeService stripe = new StripeService();! return stripe.processPayment(order);! } else {! // refuse to take money! }! }!}!!
Multiple vendors now supported but… But with each new vendor you add…
• Dependencies to customers who don’t use the vendor • Multiple if/else statements • Multiple Service implementations that achieve the same result • RISK when adding new vendors…
Take Control of Your App
“Don’t call me, I’ll call you…”
Dependency Injection Explained Dependency Injection is a technique to separate the creation of dependencies from the main class under consideration. Typically dependencies are injected in class construction or through interfaces.
Best Practice Implementation public class PaymentService {! ! private PaymentServiceProvider serviceProvider;!
! // Constructor injection! public PaymentService(PaymentServiceProvider serviceProvider) {! this.serviceProvider = serviceProvider;! }! !
public PaymentResult processPayment(CustomerOrder order) {! return this.serviceProvider.processPayment(order);! }! ! // Interface for stub! public interface PaymentServiceProvider {!
PaymentResult processPayment(CustomerOrder order);! }!!}!
The benefits of DI with Custom Metadata Apex Type + Custom Metadata + Dependency Injection = LIKE!
Customer environment configurations can completely change the behavior of logic driven from compiled code in a managed package leaving…
– Your customers more flexible and in control of their process (good thing) – Your R&D busy innovating not re-factoring (good thing) – Your app sustainable for years to come (good thing)
How to get started today? http://fonteva.io
Learn how to build a Twitter Integration WITHOUT WRITING A SINGLE LINE OF CODE using our Framework DI/IoC container. Join me and Aaron Slettehaugh (Product Manager, Custom Platform, Salesforce.com) TODAY, 12:15 PM @ Moscone Center West 2011 Learn how you can use Custom Platform, a brand new Force.com feature, along with our Framework, to build killer apps that last!
Check out the new Partner Community
https://partners.salesforce.com/
Connect with Partners in the Partner Zone The Westin Hotel, Market Street 2nd Floor – Metropolitan Ballroom INNOVATE with the leading technology • Demos of new Salesforce technology CONNECT with members of the partner community • Partner Community Theater • Networking areas • Welcome reception and daily lunch service GROW your business with resources • 70+ partner-specific sessions • ‘Ask the Experts’ consultation stations
AppBash 2014 on Wednesday Night!
Suggested Sessions and New Partner Community Page
• Build Your Own Platform on Force.com - Wednesday, 12:15 PM - 12:55 PM, Moscone Center West 2011 • Advanced Apex Enterprise Patterns - Thursday, 11:30 AM - 12:10 PM, Moscone Center West 2006
http://p.force.com/designpatterns • Session slides • Session recording (available in a few weeks) • Pattern libraries links
Please take the session survey it really helps us