Skip to Content

When you work with ABAP Objects you always need to create instances of classes. Even if you use “CREATE OBJECT” to create those instances, you probably faced with the problem, that it is not so comfortable as if you have a function for creating objects in the same way. Or, you have a complex logic to create each instance.

Background

For those cases, there is a design-pattern for creating instances. This pattern is called “Factory”-pattern. There is also a pattern called “factory-method”, which is different, because it combines the creation and relationship of objects. Thanks to Naimesh Patel, who advise me of this point.

The factory-pattern is one of the most used design pattern. It creates object instances without exposing the concrete instantiation logic. The instantiated objects will be accessable through an interface, which encapsulate the concrete implementation to the users.

In the classical GoF-Pattern, the factory-pattern looks like this:

GOF Factory

A client needs a product (a.k.a. “class”) and asks a factory for a concrete instance by passing the neccessary parameters to it. The factory creates a class of a specific interface ( “Product” ) and gives the instance back to the client. The specific interface should also be an abstract class, but by using an interface you will have a much better support for the separations-of-concerns principle.

The ABAP-way of the factory pattern

Sure, it should be very simple, to transfer the underlying UML to a ABAP class structure. But, you have much more than just a OO-language: The SAP Netweaver AS gives you some nice featues – customizing with a maintenance dialog is one of them.

So, here is my approach for the ABAP OO-Factory:

ABAP OO Factory

As you can see, the factory use informations out of a customizing table and holds all created instances in a internal table. The rest ( Interface, Concrete Classes) are simple ABAP OO Elements. By the way: If you can be sure, that the instances should not be buffered so far, you do not need an internal table with all created instances. 

At least, the “create” Method is not so complex: 

ABAP Factory Method

The customizing table should look like this:

Customizing Table

For your internal table in the factory, you should define a DDIC-Structure and Tabletype which includes the customizing information and a reference to the created instance.

One hint: Create a view on SEOCLASSTX and SEOMETAREL with the used interface as constant for “REFCLSNAME”, use it as foreign-key and you get a DDIC-based check, if the used class implements the correct interface.

And last, but not least: you need a maintenance view, created by the maintenance view generator.

 

Why should you use a factory-pattern?

With the factory pattern you centralize the create of objects within your application. By using this approach, you can manage the instantiation of objects ( “Products” ) and separate the usage of the concrete implementation logic. 

Through interfaces you introduce the design principle “separation of concerns” and you give a contract for all users of your classes. By accepting this contract the users of your interface count on the correct implementation of the contract.

Additional, you get an overview about who implements your interface and where is it used – just look in the ABAP Workbench and expand the implementation tree of your interface:

Implementation Tree in SE80

Adding new aspects to your software

Another important thing, which I have not mentioned so far: You can build your factory in a way, that you can very easy introduce proxy-classes (another design pattern) which covers new aspects – for example: logging or authentication – without changing the underlying classes.

New aspects with factory

By using this, your user does not affect, that there is another implementation – the interface, and its underlying contract is stil fulfilled.

Conclusion

The factory-pattern is an important pattern for creating object instances within your own code. With this pattern, you can get a more manageable, extensible and customizable software. 

To report this post you need to login first.

12 Comments

You must be Logged on to comment or reply to a post.

  1. Naimesh Patel
    Hello Hendrik,

    Nice to see that you are using Design Patterns. I also implement them in my developments and write about them on my blog. Check them out at ABAP Objects Design Patterns.

    I have few doubts on your Factory method implementation:

    • I think, you have missed “use” relationship between the Factory method and the YIF_OBJECT interface. Factory method uses this Interface to instantiate the object and return the object.
    • Table PT_INSTANCES – The basic purpose of the Factory is to return new object all the time. Where as Singleton returns you the object based on the key. So, I think by using the table PT_INSTANCES, you are not effectively achieving the Factory. Think of the FACTORY method of CL_SALV_TABLE. If it returns the existing object, you can only use it ONCE, but that’s not the case.

    Regards,
    Naimesh Patel

    (0) 
    1. Hendrik Brandes Post author
      Hello Naimesh,

      thank you for your useful annotations. Great to read your blog.

      For my usage, I do not want to have a direct linking between the Factory and the created object. I prefer the so called “loose coupling” principle to achieve a maximum of flexibility.

      And so, you got right: It is not the so called “factory-method”-pattern. I correct this point in my blog.

      In the origin purpose of the factory pattern, there will be a object created every time you call the create-method. But I found out, that there are some circumstances, where you need to buffer your instances. E.g. when they are very expensive to create. In my blog I comment this point, that you can do it without the buffering.

      I think, that the described factory pattern has a very important feature: You can customize the creation of objects without changing the factory implementation.

      Kind regards,
      Hendrik

      (0) 
  2. Raghavendra Prabhu Mithal
    Nice to learn something new. I just have a question. What if the object constructor require some parameter to be passed and each class has differnt constructor parameters, how can a factory produce the object.

    (0) 
    1. Hendrik Brandes Post author
      Hello,

      this is a problem, I am sometimes faced with, too. In practice, I introduce a method “initialize” in the interface, which adopt the logic of the constructor with all its necessary parameters.

      Kind regards,
      Hendrik

      (0) 
    2. Suhas Saha
      Are you assuming FACTORY method to be generic – return instance of “any” class? Generally FACTORY method is not supposed to behave this way.

      You can build a method which can do this, but that’ll be very difficult to implement due to the reasons outlined by you!

      (0) 
      1. Hendrik Brandes Post author
        No, I assume that every factory constructs defined “Products” e.g. instances. The usage of generic methods here will be very contrary.

        Due to the fact, that we create instances of a specific interface, we cannot use a constructor with specific parameters. So, I use an initializer-method.

        (0) 
  3. Massimo Coletti

    Hi Hendrik,

    I am facing a concrete problem trying to refining an existing factory pattern.

    In the RE module, i have a class CL_RECN_CONTRACT and a factory class CF_RECN_CONTRACT, with a nice method FIND, returning an instance of contract, given it’s key.

    Now I have created a custom subclass of CL_RECN_CONTRACT, in order to add some custom logic (just two/three methods) to the standard implementation, and I need a factory method for this new class. But, unfortunately, CF_RECN_CONTRACT is “final”, so I can’t create a subclassed factory with a refined implementation of FIND method. Do you have any suggestion on how to deal with this pattern?

    Thanks in advance,

    Massimo

    (0) 
    1. Hendrik Brandes Post author

      Hi Massimo,

      well, this is the my-called “Final-Class-Of-SAP”-Pattern 😉 I thought about, that the developer of the class-builder just forget to unset this flag…and many examples show that this not just a assumption…

      I do not know the classes and do not have any access to them at the moment. Have you look into the FIND-method, if the class-name is build dynamically in there? If so, try to come into this processing with your class – for example by entering your class in a special customizing-table. If the classname is hardcoded ( and I do not wish it to you ), you still have the option to enhance the find-method with an implicit enhancement.

      If you have to enhance the FIND-Method it should be possbile, that you will have to copy the whole method-coding into the enhancement section and then add your specific coding. Obviously this is not a very beautiful solution, but sometimes it should be this way.

      Kind regards,

      Hendrik

      (0) 

Leave a Reply