How easily customizable are SAP industry-specific solutions? - java

First of all, I have a very superficial knowledge of SAP. According to my understanding, they provide a number of industry specific solutions. The concept seems very interesting and I work on something similar for banking industry. The biggest challenge we face is how to adapt our products for different clients. Many concepts are quite similar across enterprises, but there are always some client-specific requirements that have to be resolved through configuration and customization. Often this requires reimplementing and developing customer specific features.
I wonder how efficient in this sense SAP products are. How much effort has to be spent in order to adapt the product so it satisfies specific customer needs? What are the mechanisms used (configuration, programming etc)? How would this compare to developing custom solution from scratch? Are they capable of leveraging and promoting best practices?

Disclaimer: I'm talking about the ABAP-based part of SAP software only.
Disclaimer 2, ref PATRYs response: HR is quite a bit different from the rest of the SAP/ABAP world. I do feel rather competent as a general-purpose ABAP developer, but HR programming is so far off my personal beacon that I've never even tried to understand what they're doing there. %-|
According to my understanding, they provide a number of industry specific solutions.
They do - but be careful when comparing your own programs to these solutions. For example, IS-H (SAP for Healthcare) started off as an extension of the SD (Sales & Distribution) system, but has become very much more since then. While you could technically use all of the techniques they use for their IS, you really should ask a competent technical consultant before you do - there are an awful lot of pits to avoid.
The concept seems very interesting and I work on something similar for banking industry.
Note that a SAP for Banking IS already exists. See here for the documentation.
The biggest challenge we face is how to adapt our products for different clients.
I'd rather rephrase this as "The biggest challenge is to know where the product is likely to be adapted and to structurally prepare the product for adaption." The adaption techniques are well researched and easily employed once you know where the customer is likely to deviate from your idea of the perfect solution.
How much effort has to be spent in
order to adapt the product so it
satisfies specific customer needs?
That obviously depends on the deviation of the customer's needs from the standard path - but that won't help you. With a SAP-based system, you always have three choices. You can try to customize the system within its limits. Customizing basically means tweaking settings (think configuration tables, tens of thousands of them) and adding stuff (program fragments, forms, ...) in places that are intended to do so. Technology - see below.
Sometimes customizing isn't enough - you can develop things additionally. A very frequent requirement is some additional reporting tool. With the SAP system, you get the entire development environment delivered - the very same tools that all the standard applications were written with. Your programs can peacefully coexist with the standard programs and even use common routines and data. Of course you can really screw things up, but show me a real programming environment where you can't.
The third option is to modify the standard implementations. Modifications are like a really sharp two-edged kitchen knife - you might be able to cook really cool things in half of the time required by others, but you might hurt yourself really badly if you don't know what you're doing. Even if you don't really intend to modify the standard programs, it's very comforting to know that you could and that you have full access to the coding.
(Note that this is about the application programs only - you have no chance whatsoever to tweak the kernel, but fortunately, that's rarely necessary.)
What are the mechanisms used (configuration, programming etc)?
Configurations is mostly about configuration tables with more or less sophisticated dialog applications. For the programming part of customizing, there's the extension framework - see http://help.sap.com/saphelp_nw70ehp1/helpdata/en/35/f9934257a5c86ae10000000a155106/frameset.htm for details. It's basically a controlled version of dependency injection. As a solution developer, you have to anticipate the extension points, define the interface that has to be implemented by the customer code and then embed the call in your code. As a project developer, you have to create an implementation that adheres to the interface and activate it. The basic runtime system takes care of glueing the two programs together, you don't have to worry about that.
How would this compare to developing custom solution from scratch?
IMHO this depends on how much of the solution is the same for all customers and how much of it has to be adapted. It's really hard to be more specific without knowing more about what you want to do.

I can only speak for the Human Resource component, but this is a component where there is a lot of difference between customers, based on a common need.
First, most of the time you set the value for a group, and then associate the object (person, location...) with a group depending on one or two values. This is akin to an indirection, and allow for great flexibility, as you can change the association for a given location without changing the others. in a few case, there is a 3 level indirection...
Second, there is a lot of customization that is nearly programming. Payroll or administrative operations are first class example of this. In the later cas, you get a table with the operation (hiring for example), the event (creation, modification...) a code for the action (I for test, F to call a function, O for a standard operation) and a text field describing the parameters of a function ("C P0001, begda, endda" to create a structure P001 with default values).
Third, you can also use such a table to indicate a function or class (ABAP-OO), that will be dynamically called. You get a developer to create this function or class, and then indicate this in the table. This is a method to replace a functionality by another one, or extend it. This is used extensively in the ESS/MSS.
Last, there is also extension point or file that you can modify. this is nearly the same as the previous one, except that you don't need to indicate the change : the file is always used (ZXPADU01/02 for HR modification of infotype)
hope this help
Guillaume PATRY

Related

If the requirements can change in future, is it a good idea to pull the business rules out of the code into a custom rule engine?

We have a requirement such that Users need to be presented different facts based on some constraints.
Similar Hypothetical Example
If User belongs to Australia and earns more than 10k$ then show XYZ view of data/facts
If User belongs to USA and earns less than 5k$ then show ABC view of data/facts
...
...
Now we can either,
keep this mapping in the user model and have these business rules in the code
or
we can pull these rules out into a JSON or a DSL where we can simply change the rule without having to deploy the code for every single change.
We dont know how frequently these rules will change.
I have read arguments for and against the idea of a custom mini rule engine.
Arguments for:
Every small change will not require a deployment
All the rules related to this specific functionality are at one place (probably) making it easier to get an overview
Arguments against:
(Martin Fowler article) It will become difficult to reason about your code
Anemic Data model anti-pattern
Over time it will be difficult to manage these rules
Conflicts between rules or the chance of some facts not belonging to any of
In general it depends on your use case. Looking at the examples you have provided it looks like an excellent application of a rules engine. By externalising that logic you'll make your application more declarative, easier to maintain, and will deliver value to your users faster.
In your case this is the key statement:
We dont know how frequently these rules will change.
That suggests that you really need to externalize that logic either to a rules engine or a DSL of your choice. If you don't you'll be signing up to deploy new code every time those rules do change.
Your examples as written are pretty classic examples of ProductionRules
https://martinfowler.com/dslCatalog/productionRule.html
https://en.wikipedia.org/wiki/Production_system_(computer_science)
There are many good open source and commercial rules engines available. I'd consider those before creating a custom DSL. The logic you've written matches very well with those systems.
Some of the technical downsides of rules engines and DSLs are:
Rules systems can be difficult to test
You have to carefully design the inputs and outputs to your rules
You'll need to understand, document, and integrate another tool or custom DSL parser
Building rules is a different mental model than some developers are used to and it can take time to do it well
There is nothing wrong having business logic abstracted. And declarative rules seem appropriate in your scenario. One should be able to extract a - human readable - report, showing the business logic, the rules applied.
So the first stage would be the requirements, what you would like as product.
This can become extra code/modeling without impeding on the existent code base.
Do not start in the wild: do not search a solution library, when the problem and solution are unclear. Often a "solution framework" is applied, and the problem modeled after that. With much boiler plate code and not exactly matching what you actually would want.
At this stage you probably could make a simple prototype of a do-it-yourself rule engine. Maybe even make a fast and rough prototype. Then look for existing rule engines, and make prototypes. Preferably not on your application, but using Test-Driven-Development in unittests.
A bad idea is to immediately leave the rules definition maintenance to the end admin users. Such functionality has implications: missing test staging, working on the production system, versioning, technical qualifications of end users like big integrative picture.
As a last remark: this might have been something for the Software Engineering forum.

Why arraycopy() does not obey the lowerCamelCase convention? [duplicate]

While studying the standard Java library and its classes, i couldn't help noticing that some of those classes have methods that, in my opinion, have next to no relevance to those classes' cause.
The methods i'm talking about are, for example, Integer#getInteger, which retrieves a value of some "system property", or System#arraycopy, whose purpose is well-defined by its name.
Still, both of these methods seem kinda out of place, especially the first one, which for some reason binds working with system resources to a primitive type wrapper class.
From my current point of view, such method placement policy looks like a violation of a fundamental OOP design principle: that each class must be dedicated to solving its particular set of problems and not turn itself into a Swiss army knife.
But since i don't think that Java designers are idiots, i assume that there's some logic behind a decision to place those methods right where they are. So i'd be grateful if someone could explain what that logic really is.
Thanks!
Update
A few people have hinted at the fact that Java does have its illogical things that are simply remnants of a turbulent past. I reformulate my question then: why is Java so unwilling to mark its architectural flaws as deprecated, since it's not like that the existing deprecated features are likely to be discontinued in any observable future, and making things deprecated really helps refraining from using them in newly created code?
This is a good thing to wonder about. I know about more recent features (such as generics, lambda's etc) there are several blogs and posts on mailing lists that explain the choices made by the library makers. These are very interesting to read.
In your case I expect the answer isn't too exiting. The reason they were made is hard to tell. But both classes exist since JDK1.0. In those days the quality of programming in general (and also Java and OO in particular) was perhaps lower (meaning there were fewer common practices, library makers had to invent many paradigms themselves). Also there were other constraints in those times, such as Object creation being expensive.
Many of those awkwardly designed methods and classes now have a better alternative. (See Date and the package java.time)
The arraycopy you would expect to be added to the Arrays class, but unfortunately it is not there.
Ideally the original method would be deprecated for a while and then removed. Many libraries follow this strategy. Java however is very conservative about this and only deprecates things that really should not be used (such as Thread.stop(). I don't think a method has ever been removed in Java due to deprecation. This means it is fairly easy to upgrade your software to a newer version of Java, but it comes at the cost of leaving some clutter in the libraries.
The fact that java is so conservative about keeping the new JDK/JRE versions compatible with older source code and binaries is loved and hated. For your hobby project, or a small actively developed project upgrading to a new JVM that removes deprecated functions after a few years is not too difficult. But don't forget that many projects are not actively developed or the developers have a hard time making changes securely, for instance because they lack a proper regression test. In these projects changes in APIs cost a lot of time to comply to, and run the risk of introducing bugs.
Also libraries often try to support older versions of Java as well as newer version, they will have a problem doing so when methods have been deleted.
The Integer-example is probably just a design decision. If you want to implicitly interpret a property as Integer use java.lang.Integer. Otherwise you would have to provide a getter method for each java.lang-Type. Something like:
System.getPropertyAsBoolean(String)
System.getPropertyAsByte(String)
System.getPropertyAsInteger(String)
...
And for each data type, you'd require one additional method for the default:
- System.getPropertyAsBoolean(String, boolean)
- System.getPropertyAsByte(String, byte)
...
Since java.lang-Types already have some cast abilities (Integer.valueOf(String)), I am not too surprised to find a getProperty method here. Convenience in trade for breaking principles a tiny bit.
For the System.arraycopy, I guess it is an operation that depends on the operating system. You probably copy memory from one location to another in a very efficient way. If I would want to copy an array like that, I'd look for it in java.lang.System
"I assume that there's some logic behind a decision to place those
methods right where they are."
While that is often true, I have found that when somethings off, this assumption is typically where you are mislead.
A language is in constant development, from the day someone proposes a new language to the day it is antiquated. In between those extremes are some phases that the language, go through. Especially if someone is spending money on it and wants people to use it, a very peculiar phase often occurs, just before or after the first release:
The "we need this to work yesterday" phase.
This is where stuff like this happens, you have an almost complete language, but the programmers need to do something to to show what the language can do, or a specific application needs a feature that was not designed into the language.
So where do we add this feature?
- well, where it makes most sense to that particular programmer who's task it is to "make it work yesterday".
The logic may be that, this is where the function makes the most sense, since it doesn't belong anywhere else, and it doesn't deserve a class of its own. It could also be something like: so far, we have never done an array copy, without using system.. lets put arraycopy in there, and save everyone an extra include..
in the next generation of the language, people will not move the feature, since some experienced programmers will complain. So the feature may be duplicated, and found in a place where it makes more sense.
much later, it will be marked as deprecated, and deleted, if anyone cares to clean it up..

DRY Principle: Angular2/Typescript and Java back end object duplication

I'm a Java developer but I've recently begun learning Angular2/Typescript. I've worked with Angular 1.x before so I'm not a complete noob :)
While working through a POC with a RESTful Spring Boot back end and Angular2 front end I noticed myself duplicating model objects on both sides a lot e.g.
Java Object
public class Car {
private Double numSeats;
private Double numDoors;
.....
}
Now in interest of Typescript and being strongly typed I'd create a similar object within my front end project:
export interface PersonalDetailsVO {
numSeats : number;
numDoors : number;
}
I'm duplicating the work and constantly violating the DRY (Don't Repeat Yourself) principle here.
I'm wondering is there a better way of going about this. I was thinking about code generation tools like jSweet but interested to hear if anyone else has come across the same issue and how they approached it.
There are two schools of thought on whether this is a violation of the DRY principle. If you're really, really sure that there's a natural mapping you would always apply to bind json in each language, then you could say that it is duplicate work; which is (at least part of) the thinking behind IDL-type languages in technologies like CORBA (but I'm showing my age).
OTOH maybe each system (the server, the client, an alternate client if anyone were to write one) should be free to independently define the internal representations of objects that is best suited to that system (given its language, what it plans to do, etc.).
In your example, the typescript certainly doesn't contain all of the information needed to define the Java "equivalent". ('number' could map to a lot of things; and the typescript says nothing about access modifiers...) Of course you can narrow that down by adopting conventions, but my point is it's not self-evident that there'd be a 1-to-1 mapping.
Maybe one language handles references more gracefully than another. Maybe one can't deal with circular references but the other can. Maybe one has reason to prefer a more flat view of the object. Maybe a lot of things.
All of that said, it certainly is true that if you modify the json structure of an object, and you're maintaining each system's internal representation independently, then you likely have to make code changes in multiple places to accommodate that single underlying change. And pragmatically, if that can be avoided it's a good thing.
So if you can come up with a code generator that processes the more expressive language's representation to create a representation for the less expressive language, and maybe at least use that by default, you may find it's not a bad thing for your project.

Aspect oriented programming - why cross cutting is the main reason

I'm currently working on a project that i need to use Aspectj in it. In the documentation , for every aspect i wrote, i need to explain what were the reasons for using this aspect and not just write the code in the main program.
In generally, i only think about reasons like code-reusing, or flexibility (meaning the program can deal without this aspect, but the aspect will make the program more effective, like check things that maybe do some trouble in the future for example), but i think it is not enough.
While searching for more reasons, i saw that many programmers wrote "cross cutting" - what is the meaning of this and why its so important reason?
EDIT:
This question was asked during my school days, when aspects were something not so common in the projects. Now, 3 years after that, and a lot of backend programming in Java (Spring) I can answer to myself with simple example: the Repository aspect - This annotation(#repository) is used on Java classes which directly access the database.For example, when an exception occurs in the class there is a handler for that exception and there is no need to add a try catch block. It doesn't restrict to particular Class, doesn't care about the domain logic, it's to all of the Classes that want to interact with databases - this is a cross cutting problem.
Cross cutting, in my eyes, is mainly to have separation of concerns, i.e. you can separate the code that handles e.g. technical things (like e.g. logging, authorization, transactions etc.) from code that handles field of domain things.
But why and when is this useful?
It is especially useful if your development organisation also separates theses things, i.e. if some developers are responsible for field of domain programming and others for technical layers.
So different persons can write their code in different places, not disturbing each other.
If the same persons write the different aspects it may still be useful to have this separation of concerns, but it is not that urgent in this case, at least not so urgent, that you want to mess with AspectJ, which introduces some additional complexity.

I18n/L10n of an API targeting developers from maximum locales [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I am already aware about the best practices for internationalizing/localizing an application so that it is consumable by maximum number of users - from geography, language and locale perspective. My question is - what are the (additional ?) best practices I need to follow if I want to make it easy for developers from across the world to consume my API?
I realize this question is very broad - so I will attempt to reduce the scope: I am particularly interested in creating a REST API and a Java client library for the aforementioned REST API.
Some of the things that come to mind are:
Provide a way for the developer to localize Strings (obvious)
Provide a way for the developer to customize locale-specific artifacts (measurements, units like currency, distance, weights etc)
Internationalize the API documentation (?? - is this done often? Is it practical?)
Beyond these measures, there are other aspects that really confuse me.
Correctness versus Simplicity:
Should I really name my classes to reflect the technical concepts on which they are based? For example, many of the design patterns may make sense to people who are well versed in English, but for developers with a different medium of instruction, they might be difficult to grasp. So, should I, in the interest of simplicity, rename DelegationInterceptor to something using simpler language? I'm wondering whether this simplification might have any (legal ??) consequences ?
Being Culture-Neutral:
Many-a-times, the easiest way for a developer to understand things is to see an example (or even a framework name) that is similar to something they see every day - which is why Pizzeria or Token Rings would be cool as example usages of my API. On the other hand, these same concepts may not be heard of in a country where most of the developers who develop to your API come from. So should I make generic examples? But then, what good are dull, boring, "generic" examples?
It'd be great if anyone could point me to any API's out there which do a good job of catering to developers from varied locales and cultures - not necessarily in the REST or Java space - anything will do.
My 3 cents: i18n best practices are not restricted to "geography, language and locale perspective". I even think that the most interesting aspect of i18n is getting to know and understand different cultures with all their richness.
To answer your question shortly: there is a book on API design written by Krzysztof Cwalina (nice first name, isn't it?) and Brad Abrams called Framework Design Guidelines. There is also some presentation on slideshare.
Anyway, I read the book and I think it is great, eye opening at least.
The longer answer... What you are referring to, is a Programming Usability. I haven't actually seen the topic covered in details (yet), but you can find many articles on Usability of Programming Languages (i.e. these slides). It seems this is pretty new discipline and the one that is pretty hard (it is a mixture of psychology, linguistics, grammar in two different sense, theory behind compilers, algorithmic, ... , and more). The most important would be of course human factor, especially inherent ability to produce errors.
Very interesting topic :)
Going through details of your question:
There is no way to create L10n API, as Localization is a process of adapting the software to local market needs. What you want to create is i18n-related API.
I don't necessary know why it has to be REST API, but to be 100% honest I am afraid that you might want to create some super-fantastic API that is actually against i18n best practices. The first things first: if you want it to be consumed by many developers, it should be regular API just like ICU. Maybe some parts of it could be exposed as RESTful API, but I am not sure why you want to do this.
As I already mentioned, there is something called ICU, especially ICU4J. I know that this API is extremely complex and not very developer-friendly, but it has one very important advantage: it does exist. And it was created by i18n experts, so it really follows best practices. Some parts are inherently complex because of nature of things - they just have to be if you want to implement the cultural support correctly. Sorry.
By the way: I might be wrong, but you said REST API, which rings a bell in my head. I believe you think of i18n support on the client side, don't you? In such case, I must ask one question: what is wrong with Globalize and/or Dojo and why you think it is better option to do everything on the server side?
OK, with Dojo I can answer the question myself: size and responsiveness.
Going through your points: "Provide a way for the developer to localize Strings (obvious)". It is not so obvious. That is, it is not as easy as you might think. If you want to do the obvious, you must be sure to understand the terms: Resource Model, Resource Organization, Locale Fall-back, Message Formatting, Machine Translation and Translation Memory.
Trust me, it is really easy to do a mistake here. On one hand, I doubt that anyone could create an API that will stop regular programmers from being lazy and hardcode strings, I doubt that it will ever happen. On the other hand, your friendly API (if you could achieve this) could easily allow reusing translations (which is i18n defect if it doesn't regard to common things like "OK", "Cancel", etc.). Also, you need to think of formatting capability so that it is (almost) impossible to introduce concatenations (very common i18n defect, preventing correct translations) and at the same time it is easy to handle multiple plural forms (still think you know best practices...?).
Proper organization and valid abstract model might help with implementation of TM and MT (that is reusing of old translations and minimizing the costs of new ones). But this is hard and very few people do it correctly (there are even some frameworks, like Play for example that implement serious misconceptions, i.e. single translation file only).
"Provide a way for the developer to customize locale-specific artifacts (measurements, units like currency, distance, weights etc)". Great idea. But please make sure that you will include formats as well. I mean that number format varies, unit varies, unit name and symbols (even for the same units) varies, but also unit placement may vary.
Some of these artifacts are already in ICU and CLDR, but for others you would actually need to get valid translations of patterns and items themselves.
From my experience it might be hard to collect the translations in the first place, yet valid ones...
"Internationalize the API documentation". Let me guess: you meant Localize, which in that case would probably be equal to Translate.
To be honest, I don't think that translating documentation of some API or Framework is all that important. Professional programmers have to have some command of English, at least be able to understand the technical documentation and write passable code (in terms of variable names and comments) - it is very unprofessional not to use English for such items.
"Correctness vs. Simplicity". I am not sure what kind of correctness you refer to. In terms of English language grammar, I would definitely favor simplicity over language correctness.
In terms of valid support for i18n, there are so many incorrect libraries already, please refrain from providing another one. As I wrote before, some things are inherently complex and they could be either done correctly (that will result in a complex API) or should not be done at all. Bringing simple, but only partially correct solution for cultural support will result in large number of defects (that I will curse you for) and the need to find even more complex workarounds. It is not worth the effort.
"Being culture neutral". Please read the book, I recommended. It covers this shortly (there is no need to go deeper, actually).
I doubt you should actually strive so much for political correctness, just avoid something you are sure my hurt somebody's feelings (don't do to others what you don't want to do unto you). That's it.
EDIT: Just two more things.
It might be a good idea to actually perform Usability tests on your API (just like you would do for User Interface). If it feels natural and intuitive, you did a great job. By doing that, you will also learn how people might want to use your library, that is you will discover additional use cases.
It is probably much harder to create programming library than to actually create a program. In case of library/API you often need to break truths that are (or at least seem to be) carved into stone, that is create something that is against common OOP/OOD principles, but is easy to use. You would also need to provide more overloads (there are many different use cases, mind you). Something as simple as formatting Date/Time in Java could really give you a headache if you want to support java.util.Date, Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, XMLGregorianCalendar, Joda Time and JSR-310.
As a side not, I am not sure if sending formatted date/times over REST API is actually the i18n best practice...

Categories