I need some insight in the correct type of design pattern to use in the following scenario:
Existing framework that will allow 3rd party developer to create modules to provide a small piece of functionality that is required by my system.
The piece of functionality involves a subset of my system that is essentially very simple: it ensures that 2 properties are available on a specific model in my system, say for example sake "Customer" and the two properties are getName and getEmailAddress.
Now, 3rd party debelopers can provide their own implementation of these which may have very complicated processes of generating these values, but my system is only concerned with the fact that these two properties must be available.
I gess the difficult part is how the 3rd party module code attaches itself to the Customer model
Create a class CustomerInfo, containing the two customer properties, and an interface CustomerInfoProvider containing this unique method:
CustomerInfo loadCustomerInfo();
Let the framework accept an instance of this interface, that the user will provide directly, or by configuring the name of a concrete class implementing this interface in a config file.
If the latter, load the class using Class.forName(...).newInstance(), and cast the result to the CustomerInfoProvider interface.
Existing framework that will allow 3rd party developer to create
modules to provide a small piece of functionality that is required by
my system.
This means there will be a contract between your system and your client's code. Any external code that needs to interact with you system needs to fulfill that contract. In OO terms, interfaces are contracts so what you need is an interface that your clients need to implement. Example:
public interface ICustomer{
public String getName();
public String getEmailAddress();
}
Visitor, if you want to keep your implementation opaque. By "opaque" I mean binary or otherwise not accessible to the user in source form to extend using normal means.
Otherwise choose either aggregation/composition, virtual methods/abstract base class or template method as circumstances dictate or suggest.
Related
I'm currently working on a rather complex ABAP application that is going to be split into several modules each performing a specific part of the job:
one for gathering some data from multiple sources;
one for displaying that data in UI (SALV grid, if that matters);
one for doing some business things based on that data.
According to my plan each module will be a global class. However, there is some logic that may need to be shared between these classes: helper subroutines, DB access logic and so on. All of this is a set of local classes at the moment.
I know could these classes global as well, but this would mean exposing them (as well as a number of internal data structures) to the public which I would not like to. Another approach would be sharing the includes with them between my global classes, but that is said to be a bad design.
So, my question is: how do real ABAPers solve problems like this?
Here is an example of how one can access a local class defined in a report.
The report with the class.
REPORT ZZZ_PJ1.
CLASS lcl_test DEFINITION FINAL.
PUBLIC SECTION.
METHODS:
test.
ENDCLASS.
CLASS lcl_test IMPLEMENTATION.
METHOD test.
WRITE 'test'.
ENDMETHOD.
ENDCLASS.
The report which uses the class.
REPORT ZZZ_PJ2.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA:
lr_object TYPE REF TO object.
CREATE OBJECT lr_object
TYPE ('\PROGRAM=ZZZ_PJ1\CLASS=LCL_TEST')
CALL METHOD lr_object->('TEST').
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
Of course this is not a clever solution as each method call would have to be a dynamic call.
CALL METHOD lr_object->('TEST').
This could be solved however by using global interfaces that would define the methods of your classes (of course if they are not static which I assume they are not). Then you have to control each of the instances through the interface. Your target would be fulfilled then, as only the interface would be exposed globally, the implementations would remain in local classes.
You may want to do some reading on Model-View-Controller design patterns. Displaying data in a UI - would be a "view". Both the gathering and updating of data would be incorporated into a "Model" . Business logic should likely be implemented as an interaction between the view and the model in a "Controller".
That said, one approach to this is would be to utilize the friendship feature offered in ABAP OO.
As an example: create the model and view classes globally but only allow them to be instantiated privately, then grant private component access to the controller. Class definitions would be follows:
CLASS zcl_example_view DEFINITION
PUBLIC
FINAL
CREATE PRIVATE
GLOBAL FRIENDS zcl_example_controller
CLASS zcl_example_model DEFINITION
PUBLIC
FINAL
CREATE PRIVATE
GLOBAL FRIENDS zcl_example_controller
CLASS zcl_example_controller DEFINITION
PUBLIC
FINAL
CREATE PUBLIC
Additionally it may be a good idea to make the controller singleton and store a reference to it in both the view and the model. By enforcing that the controller IS BOUND when the view and model are instantiated we can effectively ensure that these three classes exist as only you desire.
Stepping back to your initial problem: I sounds to me like you're already using something like a MVC pattern in your development so your only problem is that some routines shall be used publicly by both models, views and controllers.
In this case I strongly recommend to put these routines in global available classes or to implement getter methods in your already existing classes to access those functionality.
Any hacks like \PROGRAM=ZZZ_PJ1\CLASS=LCL_TEST are sometimes essential but not here imho.
If your application is as large as you make it sound, you should organize it using multiple packages. You will certainly have to deal with non-OO stuff like function modules, data dictionary objects and other things that can not be part of a class, so using classes as the basic means to organize your application won't work outside of very small and specialized applications.
Furthermore, it sounds like you have some really severe flaws embedded in your plan if you think that "DB access logic" is something that should be "shared between classes". It is hard to guess without further information, but I would strongly suggest that you enlist someone who has experience in designing and implementing applications of that scale - at least to get the basic concept right.
Say you design an API for some library.
You want to expose some data type (say Person) in the API (e.g. getAllPeople()).
Consider the following goals:
make it easy to add members to the Person (extensible)
don't introduce a dependency between the client of the library, and your implementation (coupling)
Person is likely to include internal state information that is not interesting to the client of the library
How would you go about it?
Define the Person in the library header / API package; have both the client of the library and the implementation depend on it (high coupling; very easy to extend)
Define Person in the API/header; define PersonModel extends Person in your library implementation (easy to extend; still some coupling)
Define PersonModel in the impl.; define Person extends PersonModel in the API (awful dependencies)
Define PersonModel in the impl; define Person in the API and copy the contents when needed (hard to extend; no coupling)
anything else?
In fact, Person is part of the API. It is the responsibility of the library user to choose how to decouple your API in the context of his architecture. You should not impose it.
If the user does not want to use your Person object, he has to encapsulate / copy your object.
Of course you can design Person to be extensible, but in any case it is part of the API. A user of this API is coupled to it. He has to choose when and where he needs to decouple from it and the way to do it. If Person is well designed, he might just use it everywhere. If it is poorly designed or not easy to use/extend, well he will copy the interesting part and redesign it.
When you design an API, the 'Person' kind of object should be an interface e.g. the user should not have access to the implementation. If person is an input to a service of your API, any implementation should work (Liskov principle). If Person is an output parameter, the user should get a reference, with any underlying internal implementation, there will be no coupling with the client code. It is hard when dealing with object construction, but using the *factory design patterns, you can manage even that. If there is no concrete implementation visible to the client code, you have a good API :-)
i'm using DDD architecture in my project and I need to create a class to generate a GUID to use in another class.
This class that generate my GUID is a Infrastructure Service or a Infrastructure Helper?
How I know when a class is a Helper or a Service?
Service able to serve some clients, and often this is a SOA specific entity.
Helper provides a set of methods which commonly are pure functions.
From my point of view if a class which provides the GUID generation functionality stores or uses this GUID for further needs - it is a Service class, otherwise I would say it is a Helper because simply work by principle do and forget / generate and forget.
Often if you can make method a static method - this is a helper method, it does not depends on any class state and does not affect it as well.
Glad you found an answer but you might want to rethink the question itself. What is 'Helper'? There is no such pattern or stereotype in DDD or anywhere else. Take a look at this answer. [Something]Helper is usually a sign of SRP violation or just a bad naming. For example if your language/framework does not provide Guid generation (which is highly unlikely) you can create your own GuidGenerator class. The name should reflect responsibility.
I am designing a .Net library that exposes methods all of which can be tagged only as helper methods. Takes in PersonID, RoleID etc returns calculated salary, Salary for the entire year, Bonus etc.
Is it ok to design just a static class that has methods like GetSalary(), GetBonus(), GetHistoricSalary().
Or should I have an interface ISalaryProcessor and have these methods in there ?
With option 2 the implementing class just has behaviour and not data, in trying to bring in a contract am I creating a unwanted pure fabrication ?
If you supply an interface (or several interfaces, as per ISP), your clients can provide their own implementations for parts of your library and easily switch it if needed (for example for testing purposes).
It also allows clients to program to an interface and follow LSP in their program, making the implementation decoupled from their application.
For such flexibility, I would go with interfaces.
With a static library, there is no way to switch it out and a direct dependency is introduced (against LSP).
why is it recommended to define service contract as an interface.
Any specific advantages over having them as classes?
The primary goal is separate definition of your service from implementation
The user of your service should not know anything about how you implemented your service, but he should know what operations he can do and how.
That's why its using an interface instead of class, because interface doesn't contain an implementation.
You can share your interface one time and then never worry for years even if you changing implementation of its methods every day. End users will not need to recompile the code that's using your service
Of course [there are several advantages] !
The main one is probably the ability to implement multiple classes which support said Interface and to use these classes interchangeably [with regards to the particular interface]. One of the direct uses of this is with Mock classes used for testing; This is also used with IoC (Inversion of Control) pattern, and more generally wherever we care about the "What" rather than the "Who", i.e. What matters is that whichever class is in place it behaves as per the contract (the API) regardless of "who" (which class) it is.
Another salient advantage of Interfaces is the ability to modularize behavior. For example your application may implement a concept which works, say, like a List (can be iterated over, supplies a number of items, etc.) and like a widget validator (some application specific thing). By having two interfaces "describing" this particular object, you can use instances of that class wherevever you'd use a List (and just that) and similarly you can use it as a widget validator (and just that) whereever these validator are needed. This is akin to multiple inheritance but more flexible.
In a nutshell (and some other answers started with this), the Interface defines the contract and the Class(es) implement(s) it.
Technically, a single class could do both of these things, i.e. you do not __need __ to have Interfaces, but it is very preferable to define APIs for most any behavior which may be implemented by several classes (whether multiple implementations of almost the same thing as with "mock classes", or very different classes but supplying one particular generic service/feature as say two very distinct Lists.)
Because an interface IS a contract and a class is the means to fulfill a contract. There can be many different ways to fulfill a contract based on the context, so It makes more sense to have the contracts as interfaces. which can have different implementations