function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
TehNrdTehNrd 

Visualforce controller, 100K char limit, and class inheritance, best practice?

I have a huge visualforce controller. The page it controls It has grown beyond what I ever imagined in terms of scope and features. Due to the massive amount of features and requirements I have hit the 100K character class limit. I think I can address this limit with class inheritance but please confirm I am doing this correctly.

 

"Parent" class. In this class I could store all variables, wrapper classes, and methods that are invoked from the constructor on initial page load

 

public virtual class Parent{

    public String input {get; set;}

    public Parent(){
        //Do initializations required on page load in this contructor, not child constructor.
        init();
    }
    
    public void init(){
        system.debug('Power up systems for launch!');
    }

    public void doSomethingParent(){
        system.debug('hi from parent');
    }
    
    public class wrapperClass{
        public String Name {get; set;}
    }
}

 

 

Child class that extends parent. Would contain mostly action methods called from page.

 

public class Child extends Parent{

    public void doSomethingChild(){
        system.debug('hi from child');
        doSomethingParent();
        WrapperClass test = new WrapperClass();
    }
}

 And the page which sets the controller as the "child" class. This way it can call methods in both classes.

 

<apex:page controller="Child" >
    <apex:form >
        <apex:commandButton value="Parent" action="{!doSomethingParent}"/>
        <apex:commandButton value="Child" action="{!doSomethingChild}"/>
    </apex:form>
</apex:page>

 

 

Does everything look good here. Am I following best practices?

 

Thanks,

Jason

 

Keyword: script too large

 

Best Answer chosen by Admin (Salesforce Developers) 
TehNrdTehNrd

Yup, this was definitely a good thread. Maybe it will get mentioned in the monthly force.com email.

 

I ended up going with the utility class or the Singleton-ish approach I posted about here and here. The main issue I needed to address was to simply reduce the class size of the the controller. Below are the reasons I chose this approach.

 

1) I left the "shell" method in the main controller that calls methods in the utility class. At first glance this may seem sort of strange but there is a method behind the madness. When setup this way all of the method invocations start in one class. This makes it a lot easier to track down and trace code. My page can invoke many methods in the controller and this way I know where to start looking. If some of the methods invoked from the page start in class A, and others start in class B, this makes it a pain to track down code.

 

2) There is another advantage to leaving the shell method. My unit tests that reference these methods require no changes. They can call the same method in the same location because from the perspective of the unit test nothing has changed. This is good because I know my unit test are working correctly and any changes I make elsewhere will still need to pass all the tests.

 

3) I am also passing the entire class object over to the utility methods as an argument. This may also seem like madness but I don't think it is. Some of the utility methods can reference 10+ variables in the main controller. Adding 10+ parameter to a method, I think, adds an unnecessary level of complexity. It becomes even messier when the utility method needs to call methods back in the main controller where these methods then reference variables. If I pass the entire class everything the utility method needs is included, all variables and methods. Objects (the controller class) are passed as reference so this means when I pass the entire class to the utility method use the "this" keyword it is simply a reference to the main class. Nothing is copied in memory so there should be very little overhead added as mentioned by others in this thread.

 

So that wraps it all up. Thanks to everyone for the insight and help.

 

-Jason

 

All Answers

WesNolte__cWesNolte__c

Hey Jason

 

It's always tough to say without knowing the code quite intimately (think candlelit dinners).

 

There are some tried and tested, language independent practices, that can be fun to learn, and make you feel like a whizzkid. Some of the simpler ones are:

 

Object Composition

Singleton Pattern

Facade Pattern

 

And inheritance which you've mentioned (although terminology-wise you might call the parent the super-class, and the child the sub-class). Inheritance is very cool and easy to implement, but there is a movement in some circles away from class inheritance as there are some downfalls, with tall, brittle inheritance structures being the most obvious of them. If you read up on the Gang-of-four's Design Pattern's (an oldish, but relevant design book) you'll notice that they favour composition over inheritance where possible.

 

I've probably waffled a bit too much here, but I really enjoy server-side code architecture. The other principle to always bear in mind when trying to adhere to best practices, is that they are just that, and since the world in which we live hardly presents us with perfect use-cases, we usually have to mould said practices to our specific requirements.

 

Cheers,

Wes

garybgaryb

"some downfalls, with tall, brittle inheritance structures"

 

I take it you mean when a class inherits from a class that inherits from another class etc ad infinitum? If so, I believe Force.com limits inheritance, a class can only extend another class, and that's it - the sub-class can not be sub-classed any further.

 

J, from what you say and with the same caveats as Wes, what you're doing should work. Another approach would be to componentise elements of your page - this is particularly useful if you'll be using them elsewhere later. Setting up class hierarchies is good if you have different types of "stuff" that will have some bits in common. For example, I'm currently working on an application of applications. Users have a number of pages to fill in, but they all have certain things in common; the user can save their progress, they can cancel, the page needs to be loaded, so we have relevant methods in a super class that do that - this is more Interface pattern than Inheritance. However, there are some things we want to do the same across all - or most - pages. Put these methods in the super class and use them from sub-classes that use them unchanged, and override the methods in the ones that need to work slightly differently.

 

Apologies, not sure how well versed you are in software engineering theories, so, sorry if I'm telling you to suck eggs!

WesNolte__cWesNolte__c

Here's quite a nice example of composition to get the mindgrapes a-juicing.

 

http://force201.wordpress.com/2010/03/25/using-composition-in-custom-controllers/

TehNrdTehNrd

Thanks guys. This is all pretty deep for me as I am almost completely self taught when it comes to this type of thing. I think the reason why I am leaning towards the inheritance approach is that a lot of the variables are referenced from many different methods. If these methods where dispersed across many different classes I think this could make things a little too complex. The sub class can refer to variables in the the super class as if they where in the sub class so very few syntax changes would be required.

 

Here is some additional info on how this class behaves. This is a forecasting app.

 

The constructor in this class does a lot of work. Traversing hierarchies, building hierarchies, query opps, does calculations, and sets some defaults. This is probably around 30% of the code in the class. I'm thinking I could store all of the variables, initial functions, utility type functions, and wrapper classes in the super class.

 

Then in the sub class I could add all of the methods that reference the variables with some type of user action from the page; saves, actions, etc. This way these functions could access the variables in the super class with no syntax changes and should be quite easy to re-architect. It will also reduce the size of each class and theoretically I think I would be able to split the code 50/50 between the two classes.

 

I must admit this probably isn't the way inheritance was specifically designed to be used but I think it may work best in my case. Thoughts?

rtuttlertuttle

I think in this case I'd favor using extension classes over inheritance.  I only like to use inheritance when I see myself re-using the super class for multiple objects.  A great example is the super class I wrote for dependent picklists.  It uses a super class that can work with a sub class that sets the table name to use, and has the ability to add filters to the query and such.  I use it for multiple dependent picklists so I am okay with it being a super class.

 

For a case management system I wrote where I in my noobish ways wrote my own custom controller for (never again, always use standard when you can), I started running out of space and wanted to clear this intense class up.  My method there was to use extension classes to add new features, and if they needed to communicate backwards I stored a reference to the controller from the constructor.  Then whenever you need to open something to an extension you make a public getter object.  Example below:

 

 

 

<apex:page controller="ExampleController" extensions="FeatureExtension">
<apex:form id="inputForm">
<apex:outputText value="{!widget1}"/><br/>
<apex:outputText value="{!widget2}"/><br/><br/>

<apex:commandButton value="change in controller" action="{!changeWidget}" rerender="inputForm"/>

<br/>

<apex:commandButton value="change in extension" action="{!changeWidget2}" rerender="inputForm"/>

</apex:form>
</apex:page>



public class ExampleController {
public ExampleController() {
this.widget1 = 'Initialized in controller';
}


private FeatureExtension featureExtension;

public void setFeatureExtension(FeatureExtension e) {
this.featureExtension = e;
}

public String widget1 { get; set; }
public void changeWidget() {
this.widget1 = this.featureExtension.widget2 = 'Changed from controller';
}

}


public class FeatureExtension {
public FeatureExtension(ExampleController controller) {
this.controller = controller;
this.controller.setFeatureExtension(this);
this.widget2 = this.controller.widget1;
}

private ExampleController controller;

public String widget2 { get; set; }

public void changeWidget2() {
this.controller.widget1 = this.widget2 = 'Changed from extension class';
}

}

 

Although after drafting that entire thing up I could see a good use for a super class here that handles the storage of the extensions in the main controller, but thats another post entirely.

 

 

 

-Richard

 

TehNrdTehNrd

Thanks Richard,

 

I think if I was building something from scratch I may use this approach. I simply fear that there will be way too many syntax, getter, and setter changes required.

 

The reason I like the inheritance/extends approach, while not conventional, is that it will be dead simple to implement. Probably less than 10 minutes. Simply copy and paste a few methods from the super class to sub class.

rtuttlertuttle

Very true, my goal was to getting away from my main controller so I took this approach and slowly phased that controller out.  In your case you have to have a custom controller and are pretty much stuck with it.

 

 

-Richard

mtbclimbermtbclimber

Great discussion, thanks for starting it Jason.

 

First I want to clarify a suspicion by garyb, there is no limit around the depth of an inheritance structure. I myself have a project that utilizes 3 levels and know there is no documented limit so if you hit one there is something we need to fix :)   There is a limit, however, with trigger execution depth common only in use of the term "depth" but aside from that it's completely unrelated.

 

Interfaces and composition are better in many ways as the "has a" relationship is argubaly less brittle than the "is a" relationship between two classes.   The more intimate one is with the code the less important that brittleness becomes, IMHO.  Take the mix-in pattern we applied to Visualforce controller extension as an example of this. An approach which you may also look to leverage as this is supported with custom controllers too, not just standard.

 

I know I sent you down this path with my tweet in reaction to hitting this limit (without knowing your use case) but garyb has presented the alternative I might suggest as well - break up the page into components, each with their own fraction of the controller. In this case you would probably want to break up the current controller into the pure model elements (shape) and then partition the methods into component controller actions.

 

The one thing most of these design patterns have in common is the logical breaking up of code into smaller, more succinct units. How you combine them is in some ways dependent on style but also a matter of practicality and requirements.

 

One more thing you could do pretty easily is to take the "inner" out of your inner classes. ;-)

TehNrdTehNrd

mtbclimber & garyb,

 

When you say break the page into components I assume you mean Visualforce components? I'm looking at my page and it is very custom, built for a specific need, and I can almost guarentee elements won't be used anywhere else. I'm weary to componetize simply to componentize but I may not understand all of the benefits besides reducing controler class code. Even though this would reduce the controller class size I feel like it will break up the class and page in to many different pieces that actually become even more burdensome to manage.

 

Even if I did do this some componenet controllers would need to access variables in the page controller. How would one go about passing the main controller state to the component controllers. I'm pretty sure I would have to do something like this and I'd really prefer to not introduce this type of complexity, http://wiki.developerforce.com/index.php/Controller_Component_Communication .

 

 

sforce2009sforce2009

Hey Jason,

 

Sorry for the late reply. I took the same approach that you have taken when I had a very huge class which obviously hit the 100k character limit and I had to use Inheritance concept at that time.

 

Its good that you have started with inheritance, otherwise you would have wasted your time on rework like me. In my case client's needs were changed, so I had to rework and implement inheritance. Its pretty easy to implement. Believe me I am following the same structure from then on for medium to large scale classes.

 

If you find anything betterthan this approach it may be useful to me as well.

 

Cheers

garybgaryb

mtb - thanks for correcting me on the levels of inheritance. No idea where I got that from, but thought I'd seen it, and thought I'd seen a sympton too. However, I am sad enough to dream about working with SF/Apex/VF, so maybe that's what happened :P

 

TehNrd, yes, that's what I meant by using components, and yes, it wouldn't be quick. I think there are two issues to consider - whether what you are proposing is The Right Way To Do It, and if not, is there a quick way to get to TRWTDI?

 

I don't think what you're suggesting is so heinous that you should let it prevent you doing it. It's a nice, quick trick to get you out of a pickle not entirely of your own doing, and I don't think you should feel ashamed about doing it. It's not the neatest solution, but I don't think there are any quick ways to the neatest solution.

 

So to me, it sounds like you don't have a lot of time and what you are saying sounds like your best solution given all constraints.

 

When you say "This is all pretty deep for me as I am almost completely self taught when it comes to this type of thing", do you mean programming in general? If so (and it's something you'd like to udnerstand more about), I'd recommend reading up on some software engineerings practices and patterns and trying them in your next projects. Try not to get too caught up on specifics - people can be dogmatic about practices, but like anything, it's about choosing the right tool for the job (and getting the job done!). There are people who will pontificate about the right way of doing things, don't get caught up in trying to meet their exacting standards.

 

Read up, think about how you could have applied those principles and practices on past projects, and how you can apply them in the future. But bear in mind it's a learning curve, and it'll take time. The benefits are worth perservering with. For example, things like inheritance and componetisation are indeed useful if you want to re-use things, however that's not all they are useful for. Breaking code up logically may require more thought up front, but longer term it makes it easier to make changes, fix problems, hand over to other people, amongst other things.

 

But if you're aware of this stuff and I misread your comment, I apologise for preaching! :) If you're not from a programming background, then you're doing something right, I find your (and Wes's) blog posts and responses here a massive help in my day to day work!

d3developerd3developer

In this case I'd like to say no, that's probably not best practice -- but I don't have any better suggestion.

 

I second Wes's comment on the Design Patterns book.  We should have a Design Patterns for SFDC blogathon. :)

TehNrdTehNrd

@garyb

My programming education consists of two "Intro to Programming" classes that didn't expand much beyond loops and collections. (Two becuase transfer credits didn't match and had to retake at different school) Everything else I've taught myself. Back on topic......

 

I started the inheritance approach but I don't like it. The biggest issue I had was that an action on the VF page could call method in one of two different classes. This made it a pain to track down code. All I really need to do is make my class smaller so I figured I can just make a controller uitility class that contains some methods that can be called from the main controller. My utiltiy method must have access to the variables stored in the main class. Rather that sending all of the variables needed in the method parameters, which can be alot, I just send the entire class using "this".

 

Before:

 

public class Controller{

	Boolean doSomething;
	Integer value1;
	Integer value2;
	Integer total;
		
	public void addNumbers(){
		if(doSomething == true){
			//Imagine this is a really big and long
			total = value1 + value2;
		}
	}
}

 

 

After:

 

public class Controller{

	Boolean doSomething;
	Integer value1;
	Integer value2;
	Integer total;
	
	public void addNumbers(){
		ControllerUtility.addNumbers(this);
	}
}


public class ControllerUtility{
	
	public static void addNumbers(Controller con){
		if(con.doSomething == true){
			//Imagine this is a really big and long
			con.total = con.value1 + con.value 2;
		}
	}
}

 

 

I haven't actually tried this yet as I'm not sure the the result of the addition will be applied back to the value in the main controller. I think it should, right? Thoughts?

 

-Jason

 

 

 

 

d3developerd3developer

Err... I don't think that will work.

 

 

TehNrdTehNrd

@d3developer

 

It appears to work fine. Here is a working example.

 

 

<apex:page controller="Controller" >
    <apex:form>
        Only add if checked: <apex:inputCheckbox value="{!doSomething}"/> <br/>
        <apex:inputText value="{!value1}"/> + <apex:inputText value="{!value2}"/> = <apex:outputText value="{!total}" id="total"/><br/>
        <apex:commandButton value="Add" action="{!addNumbers}" reRender="total"/>
    </apex:form>
</apex:page>

 

 

public class Controller {

    public Boolean doSomething {get; set;}
    public Integer value1 {get; set;}
    public Integer value2 {get; set;}
    public Integer total {get; set;}
    
    public void addNumbers(){
        ControllerUtility.addNumbers(this);
    }
}

 

public class ControllerUtility{
    
    public static void addNumbers(Controller con){
        if(con.doSomething == true){
            //Imagine this is a really big and long
            con.total = con.value1 + con.value2;
        }
    }
}

 

I think I like this approach best. What does the Brain Trust think?

 

 

-Jason

 

 

 

 

rtuttlertuttle

Technically that will work because objects (classes) are passed as reference.  Another way to do this with less overhead would be to create a custom object specifically for passing data like that.  I'd think it would be easier to just say:

 

this.value = StaticUtilClass.addSomeNumbers(5,6);

 

public class StaticUtilClass {

public static integer addSomeNumbers(integer a, integer b) {

return a+b;

}

}

TehNrdTehNrd

Yup, I considered that, but at what point does it become too burdensome to have 10+ parameters for that method. It is much easier just to pass the entire class over. And if it passed as a reference it should not increase heap size or anything like that.

rtuttlertuttle

Jason I would note that if you're going to do that you might as well create an extension which automatically gets the controller passed as a reference parameter.  You can then reference that active controller and manipulate the fields as you need.  Also any method marked public in an extension class can be referenced on the page directly without having to create a connection point in the main controller.

 

ie:

 

 

 

public class controllerclass {
public integer a { get; set; }
public integer b { get; set; }
public integer total { get; set; }
}

public class extensionclass {
public extension(controllerclass controller) {
this.controller = controller;
}
private controllerclass controller;  // this is a reference to your controller
public void addNumbers() {
this.controller.total = this.controller.a + this.controller.b;
}
}

<apex:page controller="controllerclass" extensions="extensionclass">
<apex:form id="inputForm">
a: <apex:outputText value="{!a}"/><br/>
b: <apex:outputText value="{!b}"/><br/>
total: <apex:outputText value="{!total}"/><br/><br/>

<apex:commandButton action="{!addNumbers}" rerender="inputForm" value="add numbers"/>
</apex:form>
</apex:page>

 

 

 

You could use this method to break up your processing into an extension, and use the controller as a data store.  Then when you need to add functionality just add methods to an extension.

 

 

-Richard

rtuttlertuttle

After reading your latest blog post I realized you're right... we all have our own styles.  I prefer extensions to spread things out, but the way you've come up with is definitely a good idea.  Passing the object by reference allows you to manipulate it in any way you need and pass it on to other methods if needed.

 

The biggest advantage I see is that you can control which methods you are exposing in case you work with other developers.  I use both approaches in my applications.  I have a utility class for each app and it handles little things that would otherwise take up a lot of space in my controller or extensions.  ie:  I have a getParameter method that returns '' instead of null when the parameter is null to avoid having to deal with it every time i reference a parameter.

TehNrdTehNrd

One of the reasons I also like the utiltiy class approach and keeping the method shell in the main controller is that the test classes that reference these methods will require very little, if any changes.

rtuttlertuttle

Good point.  I also think you're right about the heapstack.  Because a reference is just a pointer to a memory location already in the heap you should be good to pass it around without problem.

 

 

-Richard

WesNolte__cWesNolte__c

This is an awesome thread :)

 

This looks good, as Richard said there's no need to be dogmatic, only pragmatic.

 

BTW you've started to apply a Singleton-ish pattern by doing it this way, this is a very common pattern.

 

Kudos to you all!

 

Wes

TehNrdTehNrd

Yup, this was definitely a good thread. Maybe it will get mentioned in the monthly force.com email.

 

I ended up going with the utility class or the Singleton-ish approach I posted about here and here. The main issue I needed to address was to simply reduce the class size of the the controller. Below are the reasons I chose this approach.

 

1) I left the "shell" method in the main controller that calls methods in the utility class. At first glance this may seem sort of strange but there is a method behind the madness. When setup this way all of the method invocations start in one class. This makes it a lot easier to track down and trace code. My page can invoke many methods in the controller and this way I know where to start looking. If some of the methods invoked from the page start in class A, and others start in class B, this makes it a pain to track down code.

 

2) There is another advantage to leaving the shell method. My unit tests that reference these methods require no changes. They can call the same method in the same location because from the perspective of the unit test nothing has changed. This is good because I know my unit test are working correctly and any changes I make elsewhere will still need to pass all the tests.

 

3) I am also passing the entire class object over to the utility methods as an argument. This may also seem like madness but I don't think it is. Some of the utility methods can reference 10+ variables in the main controller. Adding 10+ parameter to a method, I think, adds an unnecessary level of complexity. It becomes even messier when the utility method needs to call methods back in the main controller where these methods then reference variables. If I pass the entire class everything the utility method needs is included, all variables and methods. Objects (the controller class) are passed as reference so this means when I pass the entire class to the utility method use the "this" keyword it is simply a reference to the main class. Nothing is copied in memory so there should be very little overhead added as mentioned by others in this thread.

 

So that wraps it all up. Thanks to everyone for the insight and help.

 

-Jason

 

This was selected as the best answer
d3developerd3developer

I guess I'm going to be the sole voice of dissent here. I implemented the virtual class structure TehNrd mentioned earlier (http://wiki.developerforce.com/index.php/Controller_Component_Communication) twice recently. I do think it is a bit on the complex side and doesn't make a lot of sense to me, but something about alternatives like a method in a Utilities class that does this:

 

 

static void passValue(Controller pageController, Controller componentController)
{
  pageController.value = componentController.value;
}

 

just gives me an icky feeling.  Btw, I do use utilities classes extensively, but only when my static methods are truly static.

 

Maybe we can get 'official' word on Best Practice?

 

TehNrdTehNrd

d3developer wrote:

I do think it is a bit on the complex side and doesn't make a lot of sense to me...

 


 

Hence the reason I didn't use that approach. I'm a firm believer the KISS principle. And according to this definition of a static method:

 

Static methods typically take all they data from parameters and compute something from those parameters, with no reference to variables. - source

 

This is exactly what my utility class methods are doing.

 

-Jason

rtuttlertuttle

I don't think that is what he is doing.  I think he is just moving the body of all his methods into static methods in a utility class.

 

 

controller method:
public void appendFooter(String str) {
	myStaticClass.appendFooter(this, 'Mary had a little lamb');
}

static utility class:
public static void appendFooter(Controller ctrl, String str) {
	ctrl.textField += '\n\n' + str;
}

 

 

 

Since he is passing ctrl through as a reference, this is no different than passing an object to a method for some manipulation.  Only difference is the said object is his controller class.

 

 

-Richard

TehNrdTehNrd

@rtuttle

 

Exactly!

d3developerd3developer

@rtuttle  You are right that what I needed to do was a hair more complicated than what TehNrd is doing.

 

Still, the fact that you are passing what is effectively a pointer to the controller and then manipulating the data in utility method bothers me.

 

Take the following:

 

class DataController
{
  public String name {get; set;}
 
  public DataController()
  { 
    name = 'Bob';

  }
}

class MyUtilities {

static void changeName(DataController con)
  {
    con.name = 'Jane';
  }

}

class OtherController
{


static void testMethod haveFun()
{

  DataController dataCon = new DataController();
  System.assertEquals('Bob', dataCon.name);
  MyUtilities.changeName(dataCon);
  System.assertEquals('Jane', dataCon.name);

}

}

 

Should this work? Does this work?

 

 

TehNrdTehNrd

Yes, that works, and I believe it should work.

 

Below is the code. Test class passes.

 

public class DataController{
    public String name {get; set;}
    
    public DataController(){ 
        name = 'Bob';
    }
}

public class MyUtilities {

    public static void changeName(DataController con){
        con.name = 'Jane';
    }
}

public class OtherController{

    static testMethod void haveFun(){
        DataController dataCon = new DataController();
        System.assertEquals('Bob', dataCon.name);
        MyUtilities.changeName(dataCon);
        System.assertEquals('Jane', dataCon.name);
    }
}

 

 

rtuttlertuttle

d3,

 

This isn't anything new, this is standard functionality of Java.  Primitives are passed by value and non primitives are automatically passed as reference.

 

Take the following scenario where I have an order that needs certain fields encrypted before transmitting across web service.  Now I might have some inheritance where credit orders have specific fields that need to be encrypted beyond the normal order.  The simple way to do this is to pass my order extended class and let the static class determine which fields need to be encrypted.  This demonstrates an example of inheritance that the thread started looking for, and it demonstrates Jason's approach.

 

 

 

 

public virtual class OrderInfo {
	public string sku { get; set; }
	public string name { get; set; }
	public string email { get; set; }
}
public class CreditOrder extends OrderInfo {
	public string cc { get; set; }
	public string cvc { get; set; |
}

public static void encryptTransmission(OrderInfo order) {
	order.email = EncUtility.encryptText(order.email,'hex key');
	order.sku = EncUtility.encryptText(order.sku,'hex key');

	if(order instanceof CreditOrder) {
		order.cc = EncUtility.encryptText(order.cc,'hex key');
		order.cvc = EncUtility.encryptText(order.cvc,'hex key');
	}

}

 

 

 

-Richard

d3developerd3developer

I understand that it works and how it works and I suppose for some reason it simply bothers me when applied to a controller more than other non-primitive objects. That said, I don't have anything better to suggest (especially for this case). 

Mike LeachMike Leach

Interesting thread. My thoughts on applying OOP and refactoring best practices with Apex:

 

 

  • Controller inheritance is an appropriate pattern when multiple pages share common functionality, but not really intended to reduce class size.
  • Check out Martin Fowler's book on refactoring for the various patterns available.
  • Don't let any Apex class get over 500 lines. 
  • Use merciless refactoring and make lot's of small changes along the way to avoid large scale re-writes
  • Keep test coverage above 90% at all times (to avoid backtracking and writing tests later)
  • Keep unit test classes separate from app classes. Use the @IsTest identifier so test code doesn't count against Apex line limit for org.
  • Utilize the controller strictly as an interface for binding to the UI and externalize database I/O to util or SObject specific business logic wrappers.
  • Use lazy initialization on all property get methods.
  • The #1 weakness of Apex MVC is side-effect bugs induced by a barely deterministic property setting order of execution. Minimize dependencies on the state of other properties whenever possible (easier said than done, I know )
Good luck! :-)
-Mike

 

rtuttlertuttle

Also another point about this, this static method now handles any type of order I throw at it.  If I decide to extend order into a CashOrder it will still take it just the same.  Passing a controller does seem a bit odd, but not that odd when you think its just a big class.

 

 

-Richard

d3developerd3developer

    • Keep unit test classes separate from app classes. Use the @IsTest identifier so test code doesn't count against Apex line limit for org.

    What if you have sub-classes? For instance, most of my wrapper classes are contained within the Controller in which they are used, and can't be initialized from a TestSuite.

     

    I don't quite understand how this plays out in APEX. Care to give a code example?

     

    Great advice, btw.

    d3developerd3developer

    <<  Passing a controller does seem a bit odd, but not that odd when you think its just a big class.>>

     

    Yes, but it is not just a question of whether it is odd or it works but whether or not it is best practice.

    rtuttlertuttle

    I too keep some classes internally in the controller.  I've tended to break this habit lately, but to test them you can make them public then declare a new instance like so:

     

     

    public class pagecontroller {

    public class widget {

    public string property { get; set; }

    public widget() { this.property = 'widget'; }

    }

    }

     

     

    pagecontroller.widget widg =  new pagecontroller.widget();

    system.assertEquals(widg.property,'widget');

     

     

    As for lazy initialization I see how it would be applied with a static map to the object, but my question is because the map that stores the objects is static does this also implement a singleton pattern by doing so?

     

     

    -Richard

    d3developerd3developer

    <<pagecontroller.widget widg =  new pagecontroller.widget();>>

     

    ahh. Thanks!

    Mike LeachMike Leach

    What if you have sub-classes? For instance, most of my wrapper classes are contained within the Controller in which they are used, and can't be initialized from a TestSuite.

     

    I'm personally not a fan of nesting class definitions since that limits their reuse. I would prefer to create a private instance of a public class (example below), but I imagine a public sub-class should be accessible from an external test (no?)

     

     

    public class Foo{
       private Bar bar = new Bar();
    }
    
    public class Bar{
    
    }

     

     

    I don't quite understand how this plays out in APEX. Care to give a code example?

     

     

    //Lazy initialization example
    private string m_objectID = null;
    public string ObjectID{
       get{
          if(m_objectID == null){
             m_objectID = ApexPages.currentPage.getParameters().get('oid');
          }
          return m_objectID;
       }
    }

     

     

    d3developerd3developer

    Why not do it w/ only one variable?

     

     

    public String objectID;
    
    public String getObjectID(){
    
          if(objectID == null){
             objectID = ApexPages.currentPage.getParameters().get('oid');
          }
          return objectID;
    }

     

     

    Mike LeachMike Leach

    You could start with a single public variable instead of a property, but eventually the code will evolve to require validation, globalization, and other biz rules beyond simple get/set.

     

    You want to protect access to member variables as much as possible and provide external classes with a single public interface that you control.

    d3developerd3developer

    Roger. Thanks!

    rtuttlertuttle

    Wouldn't that all be solved by setting the set to private?

     

    public String widget {

    get {

    if(widget == null) widget = '';

    return widget;

    }

    private set;

    }

     

     

    -Richard

    rtuttlertuttle

    Also I believe you can do validation inside the set method. 

     

     

    public string widget {
    	get;
    	set {
    		if(someBooleanValidation(value)) {
    			this.widget = value;
    		}
    	}
    }

     

     

    Mike LeachMike Leach

    A property definition can omit either get or set if it doesn't want to allow that interface.

     

    It should be noted that lazy init is often more of a performance optimization than anything else as it prevents unnecessary or repeated initialization of a property. It has the side effect of caching a class variable that could require refreshing if object state needs updating.