Translate

Showing posts with label Java Access Modifiers. Show all posts
Showing posts with label Java Access Modifiers. Show all posts

Tuesday, September 11, 2018

Mark Your Safe Zone! Utilizing Access Modifiers in Java


Source: https://dzone.com/articles/mark-your-safe-zone-utilizing-access-modifiers

Mark Your Safe Zone! Utilizing Access Modifiers in Java

by Mateusz Winnicki

A vast majority of methods and classes in Java are marked as public. Check out this post on one developer's thoughts on public classes and why it is unwise.

Recently, I was wondering which keyword in Java is the most used by programmers. Is it final, return, class, or maybe something else?
Unluckily, I haven’t found any broader statistic on the Internet or even on GitHub. However, I remained curious, and so, I wrote a simple file crawler and ran it on several big projects found on GitHub. The outcome was horrible.
Three of the most used keywords in projects that I noticed are — in order — public, final, and, lastly, return.
I agree that final and return can be used in almost every method and class in our programs, but I cannot believe that public is so common, let alone the most used method. 
A bell went off in my head — something is wrong. Why is the public access modifier so heavily used? I checked projects one more time only for access modifiers:
  • Public — 80%
  • Private — 17%
  • Protected — 3%
Unfortunately, I couldn’t check the default scope, as it has no keyword, but based on a number of classes in projects, I checked and can tell that the default scope count will be similar to the protected. So, the number is very little — too little!
What does it mean that almost everything is public in our code? Is it bad or is it good? Well, it is definitely not good. It is actually awful and can lead to many cases of abuse.

Why Is Public a Bad Thing?

First, we should consider why this problem occurs. My main guess is modern IDEs. Modern IDEs, like IntelliJ or Eclipse, are creating a new class by default with the visibility set to public. But, should they? Don't we already have a default modifier that is no modifier? I think that the creators of the Java language tried to save our time from writing new classes by making that. If the majority of classes and methods will be set to the default, why do we need to assign a modifier to them? I guess that was the question that they asked when they were creating the Java Language Specification.
Another option is that programmers actually don’t know how or why we should use a default modifier. Unfortunately, this leads to problems that static analyzers have the option to warn on the usage of default/protected modifier, which is really disgusting!
Ok, but why is public so wrong? Why can’t we just make everything public?
Because we should always respect the privacy of our code. For example, we respect the privacy of our friends, colleagues, and we want to keep our lives private. It is as simple as that.
But, something needs to be public, right? Yes, there is a public function in programming called an API. An API has to be public because the parameters of an API have to be public. Everything behind the API, however, has to be made not public. Of course, I am not talking about the API of our whole application. I am talking about the feature.
What is the default modifier in Java? The default modifier is a package-private visibility, which means that nobody outside our package can directly use this field, method, or class with that modifier. This approach is commonly used in the package-by-feature or hexagonal architecture in contrast to dividing code by layers or themes.

What Steps Need to Be Done to Create a New Feature?

We need to:
  • Define the public API of your feature
  • Write tests for your public API
  • Implement public APIs using many, many internal classes and methods (with the default or private modifier)
It makes no difference if we are talking about service-oriented applications or object-oriented applications. We can almost always break it down.
Let's look at an example: you want to expose a feature using the SELECT clause on the SQL database. In a standard way, there will be a public driver that will have direct access to the database, and with it, you can call anything from anywhere. Do you want to drop the database directly from the front-end? No problem. In this way, you will have a public API for the database, which will expose methods with SELECT. There won’t be an easy way to expose the whole database.
Anyone who wants to use your feature will have to access your public API to do so. Are you using database inside? No problem — nobody will be allowed to access it directly and corrupt your state. Are you calling the external system inside your feature? Still no problem; nobody will have access to that.

What Are the Benefits of This Approach?

You have a big control over your code, and as long as your public API will fulfill a contract that long, you can do whatever you want inside. You can easily refactor your behind-API code, you can divide classes, extract additional methods, breaking down responsibilities, and you will not need to think about the outside world.
Your code is easily testable; you wrote tests for your API, and now, you have a big regression suite to avoid problems in the future. Moreover, your tests are a documentation on how to use it. Keep in mind: noone forbids writing tests for your nonpublic classes. It is all right to do it when it is needed. In an example, when you have to test your super complicated algorithm or regex, it can be more complicated for testing it through the API. Just remember to not attach to this class and test. At some point, you need to delete it and forget that you ever wrote it.
As your inside classes are not accessible by the outside world, your whole solution is characterized by high cohesion. All you have to do is stick to a contract and you will be fine.
From a user perspective, all your features will be easily accessible and usable. Nobody will have to check all the codebase to know what is going on. Just look on packages and public APIs.
I don’t know why the majority of classes are public, but I know why it is a bad thing. Remember, once you expose all your classes, it will be difficult to remove them from the system in the future, as everybody can use them directly. Next time, when you are creating a new class, think and consider if it is necessary to make it public.

Friday, March 31, 2017

Java: Interface vs. Abstract Class


How to characterize concrete classes using abstract classes and interfaces in Java.

  · Java Zone
A class is named a concrete class when it has a name and implements every remaining method that is declared along the class hierarchy. Along with the hierarchy, its supertypes become a more general representation of the acting domain, and finally goes beyond that border and ends with the fact that almost everything is an object. A supertype can be either a concrete class that is apparently not final, an abstract class or even one or more interfaces. Combining a super or an abstract class with some interfaces is also a wide acknowledged way for characterizing a concrete class. Polymorphism is given when more than one class implements a particular method differently based on a class’s nature. In this article, the focus is on two of three kinds of supertypes they distinguish from their essential characteristics. Both an interface as well as an abstract class can be instantiated in a manner of an anonymous class.

Abstract Class

Typically, an abstract class implements common behaviors and member variables across any concrete class, and its method might have already specified an interface. The distinguishable behavior is gained through declaring abstract methods, which need to be implemented in a specific class. The abstract class can inherit features from another concrete or abstract class, and can enrich further behavior while adding interfaces. In Java, such tangible implementations can be explicitly emphasized with the annotation @Override that indicates a deviation of manner (docs.oracle.org, n.d.). The polymorphism stops at that point, where a concrete implementation of a method becomes final. As methods in an abstract class can also be private, it makes such a class most appropriate for encapsulating private methods while breaking down the complexity of shared methods into smaller pieces. (Martin, 2009). An abstract class is ultimately very close to a concrete implementation.

Interface

Since Java 1.8, an interface can implement default methods to provide a general behavior (Panka, 2016). Consequently, both an abstract class and an interface approach each other regarding their features. While member variables of an interface are explicitly public and final, an abstract class does not sanction their members about access modifiers. Moreover, there is a small difference with a significant effect regarding possible access modifiers for a default method in interfaces. A default method is always public and is in contrast to an abstract method that accepts either default, protected, or public as an access modifier. Whatever an interface defines, it can be used anywhere and may enrich an object with specific behaviors. An interface allows only inheritance from another interface. Both an abstract class and an interface can implement static methods. (docs.oracle.com, n.d.). Another type of interfaces are such without any declared method and are fully accepted as a marker interface. They merely indicate the compliance from a developer that, for example, a class is serializable (java.io.Serializable) or cloneable (java.lang.Cloneable) (mrbool.com, n.d.).

Example 1: Interface vs. Abstract Class

This comparison emphasizes the advantage of an abstract class over an interface focused on the calculation of the angle between two straight lines. However, both an interface and an abstract class can be used for that purpose while the first does not go in line with Martin’s suggestions about clean code.
public interface TwoDimensional {
    double PI = 3.141579; //is public and final
    default double getAngle(TwoDimensional a, TwoDimensional b) /* is public */{
        double alpha = 0.0;
        //do complex calculation here
        //modulus
        //scalar
        //to degrees
        return alpha;
    }
    int getX(); //is public
    int getY();
}

public abstract class AbstractTwoDimensional {
    public final double PI = 3.141579;
    private int x;
    private int y;
    public final double getAngle(AbstractTwoDimensional other) {
        double a = calcModulus(x, y);
        double b = calcModulus(other.getX(), other.getY());
        double s = scalar(other.getX(), other.getY());
        return toDegrees(s, a, b);
    }
    private double toDegrees(double s, double a, double b) {
        //compute
        return 0;
    }
    private double calcModulus(int x, int y) {
        //compute...
        return 0;
    }
    private double scalar(int x2, int y2) {
        //compute...
        return 0;
    }
    abstract int getX();
    abstract int getY();
    //some other abstract methods…
}

Example 2: Combination of Interface and Abstract Class

This example is very close to the prior one, but is distinguished by a mix of interface and abstract classes. They both characterize concrete classes.
public interface TwoDimensional {
    Double PI = 3.141579;
    double getAngle(TwoDimensional other);
    int getX();
    int getY();
}

public abstract class AbstractTwoDimensional implements TwoDimensional {    
    private int x;
    private int y;
    @Override
    public final double getAngle(TwoDimensional other) {
        double a = calcModulus(x, y);
        double b = calcModulus(other.getX(), other.getY());
        double s = scalar(other.getX(), other.getY());
        return toDegrees(s, a, b);
    }
    @Override
    public final int getX() {
        return x;
    }
    @Override
    public final int getY() {
        return y;
    }
    protected void setX(int x) {
        this.x = x;
    }
    protected void setY(int y) {
        this.y = y;
    }
    private double toDegrees(double s, double a, double b) {
        //compute
        return 0;
    }
    private double calcModulus(int x, int y) {
        //compute...
        return 0;
    }
    private double scalar(int x2, int y2) {
        //compute...
        return 0;
    }
}

public class MutableLine extends AbstractTwoDimensional {
    //some specific things…
    public MutableLine(ImmutableLine line) {
        //extract data and init
    }
}

public final class ImmutableLine extends AbstractTwoDimensional {
    //some specific things...
    public ImmutableLine(MutableLine line) {
        //extract data
    }
    @Override
    public final void setX(int x) {
        //throw an appropriate exception
    }
    @Override
    public final void setY(int y) {
        //throw an appropriate exception
    }
}

References

docs.oracle.org (n.d.) Anonymous Classes. Oracle. Available from: https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html. [9 February 2017].
docs.oracle.org (n.d.) Overriding and Hiding Methods. Oracle. Available from: https://docs.oracle.com/javase/tutorial/java/IandI/override.html. [10 February 2017].
Martin, R. C. (2009) Clean Code: A Handbook of Agile Software Craftsmanship. Prentice Hall. [Kindle]. [11 February 2017].
Panka, J. (2016) Java 8 Interface Changes – static method, default method. JournalDev. Available from: http://www.journaldev.com/2752/java-8-interface-changes-static-method-default-method. [9 February 2017].
docs.oracle.com (n.d.) Lesson: Interfaces and Inheritance. Available from: https://docs.oracle.com/javase/tutorial/java/IandI. [10 February 2017].
mrbool.com (n.d.) What is Marker interface in Java? Available from: http://mrbool.com/what-is-marker-interface-in-java/28557. [11 February 2017].

Source: Java: Interface vs. Abstract Class