Overusing Inheritance ?
Java Swing and Java2D rely a lot on inheritance. Most people have told me I should avoid inheritance as much as possible and only use it when necessary. So is the extensive use of Inheritance in Java2D and Java Swing justified?
Adapter Pattern
I have heard a lot of praise for the adapter pattern, and I've heard a lot of criticism. What I gathered from all that, though, is that the adapter pattern is only considered good design if used at the right place. Irrelevant use of the adapter pattern causes people reading your code to scowl. Is the adapter pattern correctly and relevantly used in the two Java APIs?
Singletons
Both APIs also tend to use a considerable number of Singletons. Is this good?
The Question
So, Is The Java2D Api and Java Swing a good example of an Object Oriented Programming Interface? Should I use their techniques in my code?
I have no certainty on this, but I can offer some thought:
inheritance: suppose you preffered to use interfaces and composition instead of reuse-by-inheritance in Swing, then you would need to do an awful lot of forwarding (Component and JComponent have dozens of methods)
adapter pattern: see above
singletons: they are appropriate to model parts of a system which are genuinely unique (I would agree that java.awt.Desktop could be implemented as a singleton -- even though it uses a factory method)
overall design: you might opt to judge things by results -- Swing is robust, extensible, and widely used.
A friend of mine who works with Swing complains constantly that it is an abstract morass. Determining the behavior of an object at run-time involves piecing together a bizarre collage of inherited functionality. From what I've seen of it I'm inclined to agree.
Inheritance is a useful programming concept, but it is easy to use
inappropriately.
Inheritance is a good choice when:
Your inheritance hierarchy represents an "is-a" relationship and not a "has-a" relationship.
You can reuse code from the base classes.
You need to apply the same class and methods to different data
types.
The class hierarchy is reasonably shallow, and other developers are
not likely to add many more levels.
You want to make global changes to derived classes by changing a
base class.
A microsoft article here and another good one here
Related
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
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I find my self writing again and again the same programming patterns in many new projects.
I have been thinking about creating my own reusable library of typical implementations of such patterns -not trying to cover all possible design patterns, but only them that experience has shown that it makes sense to put such typical implementations in a library (e.g., adapter, factory, etc ...)- but before I would like to know if there is not an existing library for this purpose already available for Java?.
I know that it is very difficult to completely generalize programming patterns in a way that they could be reused across different implementations with complex requirements (e.g., composition of patterns, classes participating in more than one pattern, etc ...). However, most of the time the pattern instantiations I need are quite simple and standard, and in many situations the implementation work could be sped up a bit with the use of such a library.
Thanks for your feedback.!
Design pattern are just... patterns. They aren't classes ready to use for anyone, but common concepts found across several projects. That's why you won't find a Design Pattern API.
This is precisely the reason why I created PerfectJPattern. Just make sure to check out and understand the code examples. They are available for download as well as in the site documentation pages for each of the Pattern implementations. If you read the GoF book, then you will understand the examples more easily.
For instance, if you want to use the Composite Pattern in your code, and if you use PerfectJPattern you only need to specify which interface (generic parameter and class instance) you would like to use as Composite and the rest is provided to you, see PerfectJPattern Composite. At the bottom of that page, a working example is provided that shows how to accomplish that.
Another aspect you should also take into account, is that in PerfectJPattern you do not necessarily need to reuse the generic Pattern implementations (e.g. perfectjpattern-core Maven submodule), you also do have the choice to only reuse the pure abstract level (perfectjpattern-api Maven submodule) and provide the implementation yourself. In PerfectJPattern you have the flexibility of reuse at different levels of abstraction since there is a fine-grained layered design reflected also in the Maven project structure. Reusing the perfectjpattern-api gives you an abstract template guideline if you wish, that will help you speed up your own Design Pattern implementations. However, ideally you should reuse as much as possible.
Update: following up on a comment below, it is worth noting that not all Patterns can be fully compotentized see From Patterns to Components. Some Patterns can be only partially componentized and some others not at all like the case of the Singleton. The Singleton depends too much on the context and that's why you can only find an interface in PerfectJPattern. However in PerfectJPattern the following Patterns are fully componentized e.g. Observer, Command, Adapter, Decorator, Composite, Proxy, Visitor, DAO, etc.
I disagree with the other answers that no reuseable implementations can be created for design patterns. However, it might not always be straightforward, and involves a lot of abstract programming.
Coming from C# I was missing the simplicity of the observer pattern in Java. (events in C#) After finishing a reusable generic observer for Java I came across the PerfectJPattern library.
It might be worthwhile to check it out.
A componentized pattern is in essence a context-independent, reusable
and type-safe variation of the original pattern that covers at least
as many use-cases as the original pattern and that does not require
developers to re-implement the same boilerplate code in every
different context. Design Patterns are reusable in terms of design,
componentized patterns are reusable in terms of design and code.
Kudos for wanting to reduce any form of duplication possible. "Don't repeat yourself" is one of the most important principles in programming.
As some extra arguments design patterns can be centralized in a library I give you some further examples:
Lazy initialization in C#.
Entire LINQ is based on IEnumerable.
Java's attempt at a reusable Observer pattern. (I didn't say all are good.)
Several patterns integrated in the Spring framework.
As in Pangea's answer: Java JT framework.
What you are looking for is PerfectJPattern.
Checkout dp4j. It allows you to implement the Singleton pattern with #Singleton and lazy initialize it with #Singleton(lazy=true). It is a "collection of reusable componentized Design Patterns implemented in Java".
For the Singleton recommend dp4j. To implement a Singleton you annotate your class with #Singleton and to lazy initialize it you annotate with #Singleton(lazy=true).
If you find yourself repeating similar code in multiple projects, it might be a good idea to extract the portions that are repeated into a library of reusable code in hopes of avoiding repeating yourself in the future.
This is unlikely to lead to fully general reusable implementations of design patterns.
JT Design Pattern Framework for Java/j2EE
A lot of the patterns are built into the Java SE - you may not notice.
Decorator is all over the java.io package.
The java.sql package is AbstractFactory.
All the wrapper classes are Flyweights.
I stand with those who say don't look for a pattern library. They should be discovered as you write your code.
It is possible in a languange which offers higher order functions and some other stuff. Here are some slides which references a paper which discusses 'the origami pattern' library. It shows 'library code' for the following patterns: Composite, Iterator, Visitor, Builder. So if you want to try that out on the jvm you can today, just use scala. http://www.slideshare.net/remeniuk/algebraic-data-types-and-origami-patterns
Do you see a forest or trees?
Design patterns should become apparent rather than be selected up front. By the time they become apparent, you don't need the pattern because the code exists. Then you marvel at how the solution solved itself and your brain subconciously selected the right approach. It gives you that warm fuzzy "i trust that code" feeling.
If you build a design pattern library, you have built yourself a big hammer (or hammer factory, or hammer factory factory [1]) and everything becomes a convenient nail (including screws) resulting in lots of sore thumbs and bowls of spaghetti in your development team.
[1] http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12
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
Not sure if the title captures what I'm trying to say here.
When designing in OO should I be splitting my objects up into their most specific areas - so if I have a factory object that deals with creating objects but later on i come across a way of creating objects for another purpose even though they may be the same objects is it worth creating a seperate fcatory or just add to the exsiting.
My biggest worry is bulking up classes with tons of stuff, or splitting objects and diluting my projects into a sea of classes.
Any help?
EDIT:
I guess on a side note/sub topic part of me wants to find out the level of granularity you should use in a program. Kind of, how low should you go?
My biggest worry is bulking up classes with tons of stuff, or
splitting objects and diluting my
projects into a sea of classes
This is a very valid point and in any even reasonably sized project, extremely difficult to get right up front especially because realistically, requirements themselves evolve over time in most cases.
This is where "Refactoring" come in. You design based on what you know at any given point and try not too make too many leaps of faith as to what you think the system MAY evolve to.
Given that you know what you are building right now, you design your classes trying to make the best possible use of OO concepts - eg encapsulation / polymorphism. This is itself, like others have noted as well, can be notoriously difficult to achieve and thats where experience, both in designing OO systems as well as knowledge of the domain can really come in handy.
Design based on what you know --> Build It --> Review it --> Refactor it --> Re-design --> and it goes on and on..
Finding the correct level of detail and responsibility is what makes OOP design so difficult. We can help you with a specific case but not with anything this general. If there were algorithms or strict methodologies of how to solve this, everyone could be an OOP designer.
A rule of thumb I like for deciding "is this getting too big now?" is "can I explain the purpose of it concisely?" If you start having to introduce caveats and lots of weasel words to explain the functions of a component of your design (be it class, member variable, method or whatever) it might be a good indicator that it's getting too complex and should be split up.
In your specific case, if you already have a factory object then the DRY Principle (Don't Repeat Yourself) would say that it's a bad idea to create another factory that does the same thing.
Is this an actual problem that you face? Or merely a fear about how your code might grow in the future?
If you are using the same type of object to solve drastically different problems then you may need to redesign the class to focus on seperation of concerns. If you need a more specific answer, you will need to provide an example of a type of class that would need this functionality.
I might have worded things badly in
the Q. I guess I wouldnt be repeating
myself its just more of a case of
where to put the code, it could be
added to an exsiting factory that
creates design objects for exporing
data to excel spreadsheets. On the
other hand I could see it could also
have its own factory for importing
excel data. Both factories would
produce the same objects but the inner
workings are completely different. –
If you aren't doing or plan on doing any class abstraction (subclassing or using interfaces) you may not need to use the factory pattern at all. The factory pattern is generally best suited for supplying objects of a base class type or that implement a specific interface.
Both
factories would produce the same
objects but the inner workings are
completely different.
Not sure if I've understood you correctly, but this sounds like a candidate for the AbstractFactory pattern.
What are the design patterns that every developer must know?
I'm interested in the context of Java web developers working with Spring & Hibernate. I have often heard that good knowledge in design patterns is essential for working with those frameworks. Can anyone list the specifics?
For example, I know that understanding abstract factory & factory pattern, singleton pattern etc is absolutely essential. I'm looking for a comprehensive list.
Inversion of Control
If you are ever going to design decoupled systems, you will need to know how to properly link dependencies between classes.
Command Pattern and Variants
In Java in particular, it is essential to learn how to pass a piece of functionality to another method as an object because of the lack of closures and function pointers in the language.
Factory Pattern
Factories are ubiquitous in Java frameworks and it is essential to learn why and when to use the factory pattern.
Singleton (pattern and anti-pattern)
Learning how to use the singleton pattern responsibly is very helpful for understanding the pitfalls in other people's code you may be reading.
Overall, learning the why with regards to patterns is much more important the the how. Knowing when not to apply a pattern is just as important as knowing when to.
Everybody should know about Singleton, but also when not to use it! It's currently the source of much pain for me on a project at work.
Singletons make the code hard to understand and follow, and make writing unit tests much more difficult. I like the blog post Singletons are Pathological Liars.
Most design patterns are pretty obvious--you already know and use them if you've been programming a few years.
The biggest advantage I've found to design patterns is sharing a common set of names. If someone says "Callback" that can mean quite a few things, but if someone says "Listener Pattern" that means a more specific set of calls and implies a higher level relationship between objects.
So in essence, read through a good design patterns book, get an idea of the name of each pattern, spend some time understanding any you don't know, and you're good to go.
I wouldn't completely ignore any of them--they are all good to have seen. You should be able to recognize a situation that might benefit from a specific pattern and know where to look to find out more about it.
Model–view–controller just has to be on the list, Spring has an MVC framework:
http://en.wikipedia.org/wiki/Model–view–controller
I recommend you to read Head First Design Patterns book. This is a well written book about all commons and useful patterns.
I would recommend you get and read the Design Patterns book, since it gives you the vocabulary.
But don't forget the fundamentals :)
Interviewing Java Developers With Tears in My Eyes
http://java.sys-con.com/node/1040135
Hibernate? Then the Unit Of Work is a must http://martinfowler.com/eaaCatalog/unitOfWork.html
Composite, it's present in the JUnit framework. (Test-TestCase-TestSuite)
The Adapter, Builder, Command, Template Method and Strategy patterns are easy and often usable in practice.
The State pattern also helped me to clean up mess in inherited source codes.
This would be a comment to Greg Hewgill's reference to "Singletons Are Pathological Liars", but I can't make comments yet.
That article makes a convincing case, but his ire is misdirected. As several commenters on his blog noted, his problem is really global state. His code fix could still be making use of singletons, and still gain the exact increase in clarity and testability.
Re-read the article. He's not bothered that OfflineQueue needs an initialized Database instance, nor that CreditCardProcessor needs an initialized OfflineQueue. He's bothered that those dependencies aren't visible, which causes issues with maintainability and testability.
His problem is with secret global state (does this make me sound like a conspiracy theorist?).
However, he's (imo) misinterpreting that secret global state as being the fault of singletons.
That doesn't mean I'm in favor of singletons where they're not necessary - certainly, they have drawbacks (including the obvious thread contention bottleneck possibility). But I prefer to be clear about what practices I'm eschewing.
Incidentally, I'd go further in my refactoring - based on the class names, I'd assert in a code review that CreditCardProcessor should, well, process the charges, so instead of his:
card.charge(cardProcessor, 100);
I'd have this, instead:
cardProcessor.chargeCard (card, 100);
(and yes, I replaced his variable names c and ccp with names I considered more readable)
Apart from Abstract factory , Factory Method and Singleton patterns, which you have quoted already, I think below patterns are useful.
Bridge Pattern : Abstraction and implementation can change independently
Decorator Pattern : Change the behaviour of object at run time
Mediator Pattern : Enable central communication medium between different objects
Chain of Responsibility : If you are adding filters to web service request, this is very useful.
Strategy Pattern : If you want to change the algorithm from a family of algorithms at run time by checking a parameter
Facade Pattern : If you have many services in your system and don't want to expose all the services to client, have one Facade class, which will interact with other services.
sourcemaking provides excellent details on each design-pattern : Intent, Strucutre, Checklist and Rules of thumb.
One more SE question would be definitely help you :
Design Patterns web based applications
Singleton - Singletons apparently can and should be used for everything