Is there a standard name for a class meant to represent another class, but keeping it distinct;
An example should help illustrate: say my business layer has access to an object of class such as .NET's System.Diagnostics.Process which contains a lot of information about the processes running on your system. Another project, such as a system resource project has no use for all that information so in the business layer, I implement a class ProcessInfo which contains only the attributes deemed to matter.
Is there a name for such intermediary, representative classes?
I'd call it a wrapper class so something like: ProcessInfoWrapper
Related
I have a Product class that contains methods and a complex data structure. I will have 8 types of products that differ only in the contents of the data structure, nothing else. In my application I will then need to create one instance of each of the 8 types of product, once, and the types of products that exist do not change at run-time.
What is the best approach and why?
A) Class Product has 8 sub-classes. Each of these sub-classes defines only the constructor. Inside each constructor the data structure is properly created for that type of product.
B) A Factory class has 8 sub-classes. Each of these sub-classes is a concrete factory for each of the 8 types of products. Class Product has no sub-classes. Each concrete factory creates the specific type of product by creating the appropriate data structure and passing it as an argument to the constructor of class Product.
I have been reviewing the advantages of the Factory design pattern and I can't see, for this specific case, any of those advantages in B over A. Am I missing something?
I would go with a variation of A, plus perhaps a factory class. A factory is meant to create classes with methods defined in an interface class, such that the consumer of the factory-created object doesn't know what type of object they are dealing with, but only the interface. The factory itself knows what type of object to create.
If there is a certain type of logic for what type of Product to create at a given time, implement a factory for 8 Products that implement an IProduct interface, and implement the logic for what type of product to create inside the factory.
I believe in Factory design pattern you can create objects of different subclasses from a single factory. See following example-
According to me using subclass approach with the factory design pattern would be a better option for the mentioned scenario.
You have mentioned - I will have 8 types of products that differ only in the contents of the data structure, nothing else.... That means state and methods are same with different contents. Based on that I feel this is clear indication that these are not subclasses but instances of same class. I think the code will contain only one product class and 8 instances of those. Factory is absolutely not required it will be unnecessary code.
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.
I have a web form that uses two classes - A and B. Class A contains all the functions I need to create CSV and Excel reports. Class B is all process-specific code.
The nature of the overall process forces me to have Class A call a method contained in Class B. The problem with that - which I just discovered - is Class A needs to create an instance of Class B to do this and Class B already creates an instance of Class A, causing an infinite loop.
What would be the proper way for me to handle this? If I could just be pointed in the right direction as far as methodology goes, I should be able to figure it out.
What do you mean by process specific code? If this is your business code then it seems clear that the separation between the two classes are that ClassA is your application service and ClassB is your business logic.
Try and untangle the classes so that your business class uses the CSV class but your CSV class doesn't use your business class.
Instead of letting each class create each other, use a constructor injection technique, in which each class take their dependency there, store in a private field, and use there instead of creating a new one, so that whatever starts this process creates both at once and passes to the other as needed.
I have the following health club scenario (coded in C++ BTW):
I want to create random Guest and Trainer objects (so both would have names randomly generated, but the guest would also have random health data).
I want to be able to make a lot of different random generators of differing complexities.
So clearly both would need the random forename/surname generator functionality - but I'm not sure how I can keep this code in one place.
I could have an abstract factory with all generation methods (e.g. generateForename()) in it that all the objects that require random generation can use. But should a trainer have access to a factory that can generate health data even though it has nothing to do with them?
I also thought about having an abstract factory for each class - so one for person, one for customer, one for guest and have objects generate their superclasses by passing them the appropriate factory but that sounds over complex for the situation.
I am fairly new to this so forgive me if my design is a bit off.
What do you guys suggest?
I'm not sure an Abstract Factory is what you're looking for. An Abstract Factory works best when you have the same base class but you need to create different concrete instances. Although you have the root base class of Person, you actually need to create derivatives of two, different base classes.
I would endeavour to keep the methods that generate data together with the class that contains that data. This way it can be reused.
Could you create a factory method on Guest and Trainer that would then be able to use the methods in their respective base classes to generate the data? Maybe create test-specific sub-classes to keep test stuff away from real stuff?
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.