Service s = new ServiceImpl() - Why you are doing that? [closed]
I just read this article SERVICE S = NEW SERVICEIMPL() - WHY YOU ARE DOING THAT?
Would like to know your views about it.. wondering 开发者_运维知识库what you will name it other than impl?
Impl
suffixes are a naming anti-pattern. It denotes the lack of effort on the developers part to descriptively name a Class
. This is the flip side of the IService
interface naming anti-pattern as well. Both practices reek of laziness or poor design choices or both. Both are code smells, that should alert the developer that something isn't right.
The fact that the code says interface Service
and class MyService implements Service
should be enough, anything else is a tautology. Even more so with today's advanced Java IDEs.
If you have a Service
interface, then name the implementations descriptively. Service
is generic, which for interfaces is good. HttpService
, AuthenticationService
are specific which for classes is good. Self documenting for the most part in both cases.
If you can't give unique descriptive names to your interfaces and classes, you are doing it wrong.
In the Mocking
argument, assuming that the real classes are in com.company.app.service
. Mock implementations should be in their own com.company.app.service.mock
package, probably in a different directory structure with the Test classes, as in Maven, which will allow them to have the same names as the non-Mock classes, and still document that they are Mocks for testing only, and not pollute the name space of the production code and make it easy to not-include that code in the deployment.
It's a common practice (probably due to a lack of imagination) among service providers. They provide you with the Service interface and their implementation. By providing you with the interface, they still allow you to create your own implementation.
Regarding the "why name is XyzImpl", I'll stick to a lack of imagination/effort.
In my opinion, the interface describes the functionality and the implementation describes how that functionality is achieved.
A classic example is the Collection library:
List
is understandable even for non-techies
ArrayList
is a List
that is implemented with a backing Array
LinkedList
is a List
that is implemented with linked nodes
This naming scheme is simple and understandable.
Another example could be DAOs:
a PersonDAO
is a DAO interface for accessing Person objects
a JdbcPersonDAO
is a PersonDAO
implemented using JDBC
a JpaPersonDAO
is a PersonDAO
implemented using JPA
etc.
Now with services, it's slightly different. Services are usually not aware of the technology underneath, so there is usually nothing that uniquely characterizes one implementation.
Service > ServiceImpl
is one way to deal with this problem, another one is IService > Service
, which is equally awful. An improvement would be the convention found in the Maven code base: Service > DefaultService
, where DefaultService
is obviously the default implementation of Service
. How about that for a reasonable naming scheme?
The better practice is to have a factory that instantiates and returns an implementation based on some configuration (with sane defaults). For example
Service s = ServiceFactory.getInstance().newService();
This allows you to use different implementations at runtime.
精彩评论