Aspect oriented programming - why cross cutting is the main reason - java

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.

Related

What is the pros and cons of centralizing applications logs? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am looking to understand the pros and cons of centralizing all applications logs into separate files with AOP (e.g. with AspectJ).
Logging is know for being a cross-cutting concern. However, I have never met anyone that centralized all logs into a single or bunch of files. Therefore, I'm left wondering why.
What would be some of the pros and cons of doing it?
I am looking to understand the pros and cons of centralizing all
applications logs into separate files with AOP (e.g. with AspectJ).
I will be using the terms AOP and AspectJ interchangeably. Notwithstanding, AOP is the paradigm and AspectJ implements it, just like OOP and Java.
The benefits of centralizing cross-cutting concerns (CCC) into their own modules (e.g., aspect) using AOP are similar to those of modularization concerns with OOP. Those benefits are described in the literature in papers and books such as:
Aspect-Oriented Programming
Towards a Common Reference Architecture for Aspect-Oriented Modeling
Impact of aspect-oriented programming on software development efficiency and design quality: an empirical study.
AspectJ in Action: Enterprise AOP with Spring
and many others. One can summarize some of those benefits as follows:
reduces code duplication; Instead of having a functionality (e.g., logging) duplicated in several different places, one has it in a single aspect. That functionality can then be applied to those several places using the concept of pointcut;
reduces the coupling between domain-related and crosscutting-related concerns (i.e., separation of concerns); For instance, removing the logging from the domain code follows the single-responsibility principle;
the enhancing of code reusability; Because of the aforementioned separation of concerns, one (for instance) increases the reusability of the modules encapsulating the based code and the modules encapsulating the logging;
dealing with code tangling and scattering issues; as illustrated in the image below
Instead of having logging 1 and 2 tangled directly with the domain-code, duplicated and scattered across separate modules (i.e., Class A and Class B), we have those logging-related functionality encapsulated into one aspect.
There are in the literature some papers about the benefit of AOP regarding the modularization of cross-cutting concerns such as logging namely:
S. Canditt and M. Gunter. Aspect oriented logging in a real-world
system. In First AOSD Workshop on Aspects, Components, and Patterns
for Infrastructure Software (AOSD-2002), March 2002.
The downsides of AOP that one can read in the literature are those typical of a learning/integrating a new technology, namely:
Hiring skilled programmers
Following an adoption path to ensure that you don’t risk the project by overextending yourself
Modifying the build and other development processes
Dealing with the availability of tools
Other downsides reported by papers such as:
An exploratory study of the effect of aspect-oriented programming on maintainability
Using aspect-orientation in industrial projects: appreciated or damned?
Using and reusing aspects in aspectj.
A Case Study Implementing Features Using AspectJ (this one is particularly good a show-casing some of issues with using AOP
can be summarize to:
having to learn a new paradigm;
lack of tool support;
the performance of the weaving;
making it harder to reason about the code, since the CCC related code was moved elsewhere. The same argument can be applied to subclassing or the use of the decorated pattern for instance. However, IDEs mitigates those problems, in the case of AspectJ by showing the joinpoints that are being intercepted. Another solution is for instance to use annotations and intercept those annotations:
#Logging
public void some_method(){...}
When the programmer looks at the annotation immediately knows that that method is being intercepted by a pointcut. The downside of this approach is that you kind mixing again the CCCs with the domain code, albeit just in a form of an annotation.
On the other hand one can argue that since the domain-related concerns and CCCs are now encapsulated in different modules it is easier to reason about them in isolation.
Pointcut fragility; This problem is similar to the fragile base class problem. From source one can read:
changes to the base-code can lead to join points incorrectly falling
in or out of the scope of pointcuts.
For instance, adding new methods, or changing their signature might cause pointcuts to intercept them or stop intercepting them. There are techniques to mitigate such problems. However, in my option the solution is tooling. When one renames a method in Java one expects the IDE to safely apply those changes.
the granularity of the joinpoint module. With AspectJ (even worse with Spring AOP) it might be difficult to get local context necessary for the logging, for instance local variables, which might force you to refactor your code so that you can expose the desired joinpoints -- known in requirements engineering as scaffolding. On the other side, refactoring your code might actually improve it. From: "21. Why can't AspectJ pick out local variables (or array elements or ...)?" one can read:
Users have sometimes wanted AspectJ to pick out many more join points,
including method-local field access, array-element access, loop iteration, method parameter evaluation
Most of these have turned out not to make sense, for a variety of
reasons: it is not a commonly-understood unit for Java programmers
there are very few use-cases for advice on the join point
a seemingly-insignificant change to the underlying program causes a
change in the join point
pointcuts can't really distinguish the join point in question
the join point would differ too much for different implementations of
AspectJ, or would only be implementable in one way
We prefer to be very conservative in the join point model for the
language, so a new join point would have to be useful, sensible, and
implementable. The most promising of the new join points proposed are
for exception throws clauses and for synchronized blocks.
You need to evaluate if in your context it pay-off adding an extra layer (i.e., transversal modularization) into your code base; and also evaluate against alternative approaches such as code-generators, frameworks or design patterns.
In the case of the logging some of the aforementioned issues are not as problematic because if things go wrong... well you just lose or add some logging.
Opinion base part
Logging is know for being a cross-cutting concern. However, I have never met anyone that centralized all logs into a single or bunch of files. Therefore, I'm left wondering why.
Is separation of concerns a bad practice?! (unless you take it to the extreme no). I would definitely say that is not a bad practice, is it worth?! well that is more complex and context depended.
I personally hate to see a beautiful snippet of code mixed with logging functionality. IMO given that software has to deal with so many other variables than just the code per si, such as tight deadlines, not having logging mixed with base code seems to not have a higher priority.

Is private necessary for a standalone Java app? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have read through a bunch of best practices online for JUnit and Java in general, and a big one that people like to point out is that fields and methods should be private unless you really need to let users access them. Class variables should be private with getters and setters, and the only methods you should expose should be ones that users will call directly.
My question: how strictly necessary are these rules when you have things like standalone apps that don't have any users? I'm currently working on something that will get run on a server maybe once a month. There are config files that the app uses that can be modified, but otherwise there is no real user interaction once it runs. I have mostly been following best practices but have run into issues with unit testing. A lot of the time it feels like I am just jumping through hoops with my unit testing getting things just right, and it would be much easier if the method or whatever was public or even protected instead.
I understand that encapsulation will make it easier to make changes behind the scenes without needing to change code all over, but without users to impact that seems a bit more flimsy. I am just making my current job harder on the off-chance it will save me time later. I've also seen all of the answers on this site saying that if you need to unit test a private method you are doing something wrong. But that is predicated on the idea that those methods should always be private, which is what I am questioning.
If I know that no one will be using the application (calling its methods from a jar or API or whatever) is there anything wrong with making everything protected? Or even public? What about keeping private fields but making every method public? Where is the balance between "correct" accessibility on pieces of code, and ease of use?
It is not "necessary", but applying standards of good design and coding principles even in the "small" projects will help you in the long run.
Yes, it takes discipline to write good software. Languages are tools that help you accomplish a goal. Like any tool, they can be misused, and when misused can be dangerous. Power tools, like a table saw, can be very dangerous if misused, so if you care about your own safety you always follow proper procedure, even if it might feel a little inconvenient (or you end up nicknamed "stubby").
I'd argue that it's on the small projects, where you want to cut corners and "just write the code", that adhering to the best practices is most important. You are training yourself in the proper use of your tools, so when it really matters you do the right thing automatically.
Also consider that projects that start out "small" can evolve over time to become quite large as you keep adding enhancements and new functionality. This is the nature of agile software development. If you followed best practices from the start you'll find it much easier to adapt as the project grows.
Another factor is that using OOP principles is a way of taming complexity. If you have a well-defined API and, for example, use only getters and setters, you can partition off the API from the implementation in your own mind. After writing class A, when writing a client of A, say B, you can think only about the API. Later when you need to enhance A you can easily tell what parts of A affect the API vs what parts are purely internal. If you didn't use encapsulation you'd have to scan your entire codebase to see if a change to A would break something else.
Do I apply this to EVERYTHING I write? No, of course not. I don't do this with short single-use scripts in dynamic languages (Perl, AWK, etc) but when writing Java I make it a point to always write "good" code, if only to keep my skills sharp.
There is generally no necessity to follow any rules as long as your code compiles and runs correctly.
However code style "best practices" have proven to enhance code quality, especially over time when a project develops/matures. Making fields private makes your code more resilient to later changes; if you ommit the getters/setters and access fields directly, any changes to a field impact related code much more directly.
While there is seemingly no advantange in a getter/setter at first, the advantage lies in the future: A getter forces any code working with the attribute through a single point of control which in case of any changes related to that field helps either mask the concrete representation/location of the field and/or allows for polymorphism when required whithout changes/checking all the existing callers.
Finally the less surface (accessible methods/fields) a class exposes to other classes (users) the less you have to maintain. Reducing the exposed API to the absolute minimum reduces coupling between classes, which again is an advantage when something needs to be changed. Striving to hide the inner workings of every object as good as possible is not a goal by itself, its the advantages that result from it that are the goal.
As always, good balancing is always required. But when in doubt, it is better to error/lean on the side of "source code quality" practices; instead of taking too many shortcuts; as there are many different aspects in your "simple" question one should consider:
It is hard to anticipate what will happen to some piece of software over time. Yes, you don't have any users today. But you know what: one major property of great tools is ... as soon as other people see them, they want to use them, too. And all of a sudden, you have users. And feature requests, bug reports, ... and make no mistake: first people will love you for the productivity gain from your tool; and then they will start to put pressure on you because all of a sudden your tool is essential for other people to make their goals.
Many things are fine to be addressed via convention. Example: sometimes, if I would only be using public methods of my "class under test", unit tests become more complicated than necessary. In such a case, I absolutely have no problem about putting a getter here or there that allows me to inspect the internal state of my "class under test"; so that my test can trigger some activity; and then call the getter. I make those methods "package protected"; and I put a // used for unit testing above them. I have not seen problems coming out of that informal practice. Please note: those methods should only be used in test cases. No other production class is supposed to call them.
Regarding the core of your question on private stuff: I think, one should always hide implementation details from the outside. Whenever you write a piece of code that is supposed to live longer than the next hour, you should do the right thing - and try to write code with very high quality. And making the internals of your objects visible on the outside
comes only with drawbacks; there is nothing positive in doing so.
Good OO is about using models that come with certain behavior.
Internal state should stay internal; there is no benefit in
exposing. For the record: sometimes, you have simple data
containers. Classes that only have some fields, but no methods on
them. In that case, yeah, make the fields public; there is (not
much) advantage in providing getters/setters. ( See "Clean Code" by
Robert Martin, chapter 6 on "Objects and Data structures")

when and why do we need to divide a class into many classes?

I am an android beginner developer. Currently, I am developing an application. However, my class is quite large because there are many UI components (to handle onClick, onProgressBarChanged, etc.).
Most of my components are dynamic. So, I have method to create those components.
Now I split some methods for initializing UI components into another class.
At this point, I am trying to think/search for a good reason to split my class into several classes.
Advantage: maintainability, testability, reusability
Disadvantage: reduce runtime performance
I am not sure that there is any advantage or disadvantage that I have missed?
Furthermore, I will divide a class when I find an overlap method
I am not sure that there is another situation when a class must be divided.
First, if you've never looked into refactoring, then I would strongly encourage you to do so. Martin Fowler has some excellent resources to get you started. But, I'm getting slightly ahead of myself.
To begin with, you split out classes to maintain a clear delineation of responsibilities. You can think of the SOLID principle here - each class does one thing, and one thing very clearly.
If you notice that a method, let alone a class, is doing more than one thing, then that is a good time to stop and refactor - that is, take the code you have, and apply a particular, focused refactoring to it to improve readability and flow, while maintaining the same functionality. You're essentially looking for code smells - parts of the code that are suspect, not following a specific contract or methodology, or are legitimate anti-patterns - which are, themselves, practices that developers strive to avoid.
Programs that deal with UI (especially in Java) tend to be pretty verbose. What you should avoid doing is placing any conditional business logic in the UI layer, for ease of separability, testing and clarity. Make use of the Model-View-Controller pattern to understand and abstract away the necessary separations between the UI (Views), and the actual work that's needed to be done (Controllers), while maintaining some semblance of state (Models).
We use OOPs Concept in Android(core java) Application Development. If we split our one class in many class it gives a good sense of maintainability, re-usability, Security and Easy change in Coding during Development.
As for example:- Util class for Database handling, Network Class for Internet connection , Dialog class for different type dialog and so...
This way we can categories our coding and change or re use it any time. So it is good practice to follow the OOPS concept during Development.
Thanks

Coupling/Cohesion

Whilst there are many good examples on this forum that contain examples of coupling and cohesion, I am struggling to apply it to my code fully. I can identify parts in my code that may need changing. Would any Java experts be able to take a look at my code and explain to me what aspects are good and bad. I don't mind changing it myself at all. It's just that many people seem to disagree with each other and I'm finding it hard to actually understand what principles to follow...
First, I'd like to say that the primary reason you get such varying answers is that this really does become an art over time. Many of the opinions you get don't boil down to a hard fast rule or fact, more it comes down to general experience. After 10-20 years doing this, you start to remember what things you did that caused pain, and how you avoided doing them again. Many answers work for some problems, but it's the individual's experience that determines their opinion.
There is really only 1 really big thing I would change in your code. I would consider looking into what's called the Command Pattern. Information on this shouldn't be difficult to find either on the web or in the GoF book.
The primary idea is that each of your commands "add child", "add parent" become a separate class. The logic for a single command is enclosed in a single small class that is easy to test and modify. That class should then be "executed" to do the work from your main class. In this way, your main class only has to deal with command line parsing, and can lose most of it's knowledge of a FamilyTree. It just has to know what command line maps into which Command classes and kick them off.
That's my 2 cents.
I can recommend Alan's and James's book Design Patterns explained -- A new perspective on object-oriented design (ISBN-13: 978-0321247148):
It's a great book about has-a and is-a decissions, including cohesion and coupling in object-oriented design.
In short:
Cohesion in software engineering, as in real life, is how much the elements consisting a whole(in our case let's say a class) can be said that they actually belong together. Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.
One way of looking at cohesion in terms of OO is if the methods in the class are using any of the private attributes.
Now the discussion is bigger than this but High Cohesion (or the cohesion's best type - the functional cohesion) is when parts of a module are grouped because they all contribute to a single well-defined task of the module.
Coupling in simple words, is how much one component (again, imagine a class, although not necessarily) knows about the inner workings or inner elements of another one, i.e. how much knowledge it has of the other component.
Loose coupling is a method of interconnecting the components in a system or network so that those components, depend on each other to the least extent practically possible…
In long:
I wrote a blog post about this. It discusses all this in much detail, with examples etc. It also explains the benefits of why you should follow these principles. I think it could help...
Coupling defines the degree to which each component depends on other components in the system. Given two components A and B ,how much code in B must change if A changes.
Cohesion defines the measure of how coherent or strongly related the various functions of a single software component are.It refers to what the class does.
Low cohesion would mean that the class does a great variety of actions and is not focused on what it should do. High cohesion would then mean that the class is focused on what it should be doing, i.e. only methods relating to the intention of the class.
Note: Good APIs exhibit loose coupling and high cohesion.
One particularly abhorrent form of tight coupling that should always be avoided is having two components that depend on each other directly or indirectly, that is, a dependency cycle or circular dependency.
Detailed info in below link
http://softwarematerial.blogspot.sg/2015/12/coupling-and-cohesion.html

How easily customizable are SAP industry-specific solutions?

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

Categories