Design Pattern
Object Oriented Design
Object Oriented Design Principles are core of OOPS programming but I have seen most of Java programmer chasing design patterns like Singleton pattern, Decorator pattern or Observer pattern but not putting enough attention on Object oriented analysis and design or following these design principles. I have regularly seen Java programmers and developers of various experience level who either doesn’t heard about these OOPS and SOLID design principle or simply doesn’t know what benefits a particular design principle offers or how to use these design principle in coding.
Bottom line is always strive for highly cohesive and loosely couple solution, code or design and looking open source code from Apache and Sun are good examples of Java design principles or how design principles should be used in Java coding. Java Development Kit follows several design principle like Factory Pattern in BorderFactory class, Singleton pattern in Runtime class and if you interested more on Java code read Effective Java by Joshua Bloch , a gem by the guy who wrote Java API. My another personal favorite on object oriented design pattern is Head First Design Pattern by Kathy Sierra and others and Head First Object Oriented Analysis and Design.
Though best way of learning design principles or pattern is real world example and understanding the consequences of violating that design principle, subject of this article is Introducing Object oriented design principles for Java Programmers who are either not exposed to it or in learning phase. I personally think each of these design principle need an article to explain it clearly and I will definitely try to do it here but for now just get yourself ready for quick bike ride on design principle town
Object oriented design principle 1 – DRY (Don’t repeat yourself)
As name suggest DRY (don’t repeat yourself) means don’t write duplicate code, instead use abstraction to abstract common things in one place. if you use a hardcoded value more than one time consider making it public final constant, if you have block of code in more than two place consider making it a separate method. Benefit of this SOLID design principle is in maintenance. Its worth to note is don’t abuse it, duplicate is not for code but for functionality means if you used common code to validate OrderID and SSN it doesn’t mean they are same or they will remain same in future. By using common code for two different functionality or thing you closely couple them forever and when your OrderID changes its format, your SSN validation code will break. So be aware of such coupling and just don’t combine anything which uses similar code but are not related.
Object oriented design principle 2 – Encapsulate what varies
Only one thing is constant in software field and that is “Change”, So encapsulate the code you expect or suspect to be changed in future. Benefit of this OOPS Design principle is that Its easy to test and maintain proper encapsulated code. If you are coding in Java then follow principle of making variable and methods private by default and increasing access step by step e.g. from private to protected and not public. Several of design pattern in Java uses Encapsulation, Factory design pattern is one example of Encapsulation which encapsulate object creation code and provides flexibility to introduce new product later with no impact on existing code.
Object oriented design principle 3 – Open Closed principle
Classes, methods or functions should be Open for extension (new functionality) and Closed for modification. This is another beautiful object oriented design principle which prevents some-one from changing already tried and tested code. Ideally if you are adding new functionality only than your code should be tested and that’s the goal of Open Closed Design principle.
Object oriented design principle 4 – Single Responsibility Principle (SRP)
There should not be more than one reason for a class to change or a class should always handle single functionality. If you put more than one functionality in one Class in Java it introduce coupling between two functionality and even if you change one functionality there is chance you broke coupled functionality which require another round of testing to avoid any surprise on production environment.
Object oriented design principle 5 – Dependency Injection or Inversion principle
Don’t ask for dependency it will be provided to you by framework. This has been very well implemented in Spring framework, beauty of this design principle is that any class which is injected by DI framework is easy to test with mock object and easier to maintain because object creation code is centralized in framework and client code is not littered with that.There are multiple ways to implemented Dependency injection like using byte code instrumentation which some AOP (Aspect Oriented programming) framework like AspectJ does or by using proxies just like used in Spring.
Object oriented design principle 6 – Favour Composition over Inheritance
Always favour composition over inheritance if possible. Some of you may argue this but I found that Composition is lot more flexible than Inheritance. Composition allows to change behaviour of a class at runtime by setting property during runtime and by using Interfaces to compose a class we use polymorphism which provides flexibility of to replace with better implementation any time. Even Effective Java advise to favor composition over inheritance.
Object oriented design principle 7 – Liskov Substitution Principle (LSP)
According to Liskov Substitution Principle Subtypes must be substitutable for super type i.e. methods or functions which uses super class type must be able to work with object of sub class without any issue”. LSP is closely related to Single responsibility principle and Interface Segregation Principle. If a class has more functionality than subclass might not support some of the functionality and does violated LSP. In order to follow LSP design principle, derived class or sub class must enhance functionality not reducing it.
Object oriented design principle 8 – Interface Segregation principle (ISP)
Interface Segregation Principle stats that a client should not implement an interface if it doesn’t use that. this happens mostly when one interface contains more than one functionality and client only need one functionality and not other.Interface design is tricky job because once you release your interface you can not change it without breaking all implementation. Another benefit of this desing principle in Java is, interface has disadvantage to implement all method before any class can use it so having single functionality means less method to implement.
Object oriented design principle 9 – Programming for Interface not implementation
Always program for interface and not for implementation this will lead to flexible code which can work with any new implementation of interface. So use interface type on variables, return types of method or argument type of methods in Java. This has been advised by many Java programmer including in Effective Java and head first design pattern book.
Object oriented design principle 10 – Delegation principle
Don’t do all stuff by yourself, delegate it to respective class. Classical example of delegation design principle is equals() and hashCode() method in Java. In order to compare two object for equality we ask class itself to do comparison instead of Client class doing that check. Benefit of this design principle is no duplication of code and pretty easy to modify behaviour.
All these object oriented design principle helps you write flexible and better code by striving high cohesion and low coupling. Theory is first step but what is most important is to develop ability to find out when and to apply these design principle and find our whether we are violating any design principle and compromising flexibility of code. but again as nothing is perfect in this world, don’t always try to solve problem with design patterns and design principle they are mostly for large enterprise project which has longer maintenance cycle.
Creational Patterns
Can be used to instantiate objects, directly or indirectly.
1. Abstract Factory: - Creates an instance of several families of classes. Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
2. Builder-: Separates object construction from its representation. Separate the construction of a complex object from its representation so that the same construction processes can create different representations.
3. Factory Method: - Creates an instance of several derived classes. Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
4. Prototype-: A fully initialized instance to be copied or cloned. Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
5. Singleton: - A class of which only a single instance can exist. Ensure a class only has one instance, and provide a global point of access to it.
Structural Patterns
it can be used to organize your program into groups.
This grouping will provide you clarity and will enable you for easier maintainability.
1. Adapter: - Match interfaces of different classes. Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
2. Bridge: - Separates an object’s interface from its implementation. Decouple an abstraction from its implementation so that the two can vary independently.
3. Composite: - A tree structure of simple and composite objects. Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
4. Decorator: - Add responsibilities to objects dynamically. Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality.
5. Facade: - A single class that represents an entire subsystem. Provide a unified interface to a set of interfaces in a system. Facade defines a higher-level interface that makes the subsystem easier to use.
6. Flyweight: - A fine-grained instance used for efficient sharing. Use sharing to support large numbers of fine-grained objects efficiently. A flyweight is a shared object that can be used in multiple contexts simultaneously. The flyweight acts as an independent object in each context it’s indistinguishable from an instance of the object that’s not shared.
7. Proxy: - An object is representing another object. Provide a surrogate or placeholder for another object to control access to it.
Behavioral Patterns
It can be used to define the communication and control flow between objects.
1. Chain of Resp: - A way of passing a request between a chain of objects. Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
2. Command: - Encapsulate a command request as an object. Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
3. Interpreter: - A way to include language elements in a program. Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
4. Iterator: - Sequentially access the elements of a collection. Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
5. Mediator: - Defines simplified communication between classes. Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
6. Memento: - Capture and restore an object's internal state. Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
7. Observer: - A way of notifying change to a number of classes. Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
8. State: -Alter an object's behavior when its state changes. Allow an object to alter its behavior when it’s internal state changes. The object will appear to change its class.
9. Strategy: - Encapsulates an algorithm inside a class. Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
10. Template: -Defer the exact steps of an algorithm to a subclass. Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing.
Software design principles represent a set of guidelines that helps us to avoid having a bad design.
Design patterns are used and supported extensively throughout the Java APIs. Here are some examples:
There is also the whole underlying (overarching?) theme of MVC, where the JSP Pages represent the View, the FrontController/Helper classes and Session Beans the Control, and the Entity Beans the model.
• How will you design your Singleton Patten class to be thread-safe? (a standard interview question!) - Adding synchronized keyword to the getSingleton() method is inefficient solution. Initialize the static private Singleton object within Synchronized block. In this way you can achieve it.
• What Design Pattern can be used for classical Producer Consumer problem? (a simple question) - Use observer pattern (publisher subscriber model)
• M.S Word can store million lines of text. Each character in the text will have set of properties like font-color, font-size, font-style and etc. So, M.S Word application has to maintain a property structure for each and every character and that may lead to heavy storage. What design pattern will you apply to overcome this problem? - You have to create property group for each possible styles (font-size, font-color, font-face & etc). So, common characters will be part of a property group, there by reducing the storage of each character. This is called FlyWeight Pattern.
• Your application uses 1000 classes and they have interaction among each other. This will lead to complex communication across objects, so what design pattern can solve this problem? - Use Mediator pattern to separate the direct communication across objects.
• An application reads input from various clients in multiple stages and creates a binary tree structure out of all received inputs. Which design pattern can be used to design such application? - Building an object in multiple set - you call it Builder pattern! The realworld example is XSDBuilder class in Java.
• You have to design a budget management application for global users. But, have to provide an option to configure their native tax rules. Which design pattern, do you think, can solve this? - Use Template Pattern. It provides templates of methods and allowing you to override certain portion of logic.
• You have a core application class. But, you have to be able assign extra functionalities to the core class on the fly (at runtime). Which patterns deserves this purpose? - Decorator Pattern. This is similar to the pattern designed for java.io.* classes(BufferedReader, DataInputStream and etc.)
while(){
initialize all thread..........
start the thread..
add in group...
}
........................
while(threadActivatedFlag )
{
if(threadGroup.activeCount()==0)
threadActivatedFlag = false;
else
Thread.sleep(4000);}
-----------------------------------------------------------------------------------------------------------------------------------------------
1. Write a Java program to create three threads namely A, B, C and make them run one after another. (C has to run after B completes, B has to run after A completes).
2. What happens when a thread calls notify() but no thread(s) is waiting?
3. How will you declare a timer variable that will be accessed by multiple threads very frequently?
4. How will you synchronize static variables?
5. What happens when threads are waiting, but never being notified?
1. Many ways to do it. I prefer join(). When a thrad A calls b.join(), then A runs only after thread b completes. So, for this problem, C has to call b.join() and B has to call a.join()
2. Actually…, nothing the notify() call simply returns.
3. Declare the variable as volatile. Every thread caches a copy of instance variable, work with local copy, and then sync it with master copy. But, threads do not cache a copy of volatile instance variable.
4. Obtain class level lock. synchronized( obj.getClass()) {……..}
5. Leaving the answer to readers!
-----------------------------------------------------------------------------------------------------------------------------------------------
1. You need to insert huge amount of objects and randomly delete them one by one. Which Collection data structure is best pet?
2. What goes wrong if the HashMap key has same hashCode value?
3. If hashCode() method is overridden but equals() is not, for the class ‘A’, then what may go wrong if you use this class as a key in HashMap?
4. How will you remove duplicate element from a List?
5. How will you synchronize a Collection class dynamically?
1. Obviously, LinkedList.
2. It leads to ‘Collision’ wherein all the values are stored in same bucket. Hence, the searching time increases quad radically.
3. Left to Readers.
4. Add the List elements to Set. Duplicates will be removed.
5. Use the utility method
-----------------------------------------------------------------------------------------------------------------------------------------------
Open Close Principle
"Software entities like classes, modules and functions should be open for extension but closed for modifications."
OPC is a generic principle. You can consider it when writing your classes to make sure that when you need to extend their behavior you don�t have to change the class but to extend it. The same principle can be applied for modules, packages, libraries. If you have a library containing a set of classes there are many reasons for which you�ll prefer to extend it without changing the code that was already written (backward compatibility, regression testing, �). This is why we have to make sure our modules follow Open Closed Principle.
When referring to the classes Open Close Principle can be ensured by use of Abstract Classes and concrete classes for implementing their behavior. This will enforce having Concrete Classes extending Abstract Classes instead of changing them. Some particular cases of this are Template Pattern and Strategy Pattern.
Dependency Inversion Principle
"High-level modules should not depend on low-level modules. Both should depend on abstractions."
"Abstractions should not depend on details. Details should depend on abstractions."
Dependency Inversion Principle states that we should decouple high level modules from low level modules, introducing an abstraction layer between the high level classes and low level classes. Further more it inverts the dependency: instead of writing our abstractions based on details, the we should write the details based on abstractions.
By applying the Dependency Inversion the modules can be easily changed by other modules just changing the dependency module. Factories and Abstract Factories can be used as dependency frameworks, but there are specialized frameworks for that, known as Inversion of Control Container.
Interface Segregation Principle
"Clients should not be forced to depend upon interfaces that they don't use."
For example if we create an interface called Worker and add a method lunch break, all the workers will have to implement it. What if the worker is a robot?
"As a conclusion Interfaces containing methods that are not specific to it are called polluted or fat interfaces. We should avoid them.
Reactor
Recently, I went to a restaurant in Bangalore. There was a female standing outside, receiving all the people entering the restaurant. She received us with a pleasant smile, then took us inside, and helped us find a table. She assigned a waiter to serve us, and then went back to the reception and waited for new clients. All she did was receive a new visitor. She is just like a web server serving multiple clients. In a typical web server, there is a thread simply waiting for requests from clients. Whenever there is a client request, it creates a separate thread and assigns that thread to handle the request. The thread will die down after serving the requests.
Facade
Imagine you want to organize a marriage reception. You need to decorate the hall where the event is planned. You need a music band to play some music. You want to organize dinner for say 100 people, and also snack in the evening for around 50 people. If you wanted to organize such an event some 10 years back, you wanted to go to a caterer for food, a musical troop for music, and organize flowers and people to decorate them, and so and so. Some twenty years back, we needed to go to the fish market, the meat shop, the vegetable market etc., for the raw materials for the food and then organize a cook so that you have everything ready for the event. Now, life is really simpler with event managers. You just need to walk to an event manager and tell him that you need a hall decorated with flowers, dinner for 100 people, snacks for 50 people, and need a good music troop to play music while the reception is going on. You don’t need to worry about anything, and they will take care of the rest. This is a typical example for Façade. You don’t need to interact with many different objects for each and every activity. You will be provided a single interface which will act as a façade for many activities. This makes the life of clients much simpler.
Other examples for Facade are one stop bill payment shops, a support desk in a big organization which takes all kinds of support requests etc.
Decorator
A decorator decorates something. An example for Decorator is a sunglass. It takes light as input, removes all harmful parts in the light, and passes it on. If you give apple as an input to a system, and if it gives orange as output, that is not a Decorator. Another example for this is music filtering.
A software example for Decorator is JAVA I/O. Initially, I wondered why we need to create so many objects just to do a file operation. I realized how flexible and wonderful it is after some time.
Template
A typical example for the Template pattern is the Computer Engineering degree curriculum. It covers all the basic stuff required for a typical software engineer. He can’t work as it is in an industry as he needs to fill in many gaps which are required in the specific domain. But, he will have the necessary knowledge to move to any software company after completion of the course.
Adapter
I think this is a self explanatory pattern. You can find many real life examples for this pattern, and the simplest, which is called by the same name, is a power adapter. You have an AC power supply and the responsibility of the adapter is to provide different types of sockets adapted to the one needed.
Another example for this is a translator who is translating languages spoken by one person for another person.
Factory Pattern and Abstract Factory pattern
Imagine you are constructing a house and you approach a carpenter for a door. You give the measurement for the door and your requirements, and he will construct a door for you. In this case, the carpenter is a factory of doors. Your specifications are inputs for the factory, and the door is the output or product from the factory.
Now, consider the same example of the door. You can go to a carpenter, or you can go to a plastic door shop or a PVC shop. All of them are door factories. Based on the situation, you decide what kind of factory you need to approach. This is like an Abstract Factory.
Observer pattern
A typical example for the Observer pattern is the conventional mail delivery system. Whenever you have a mail, the postman will come and knock at your door with the mail. Just imagine if you have to go to the post office every day and check whether there are any mails. It would have been a really inefficient system as each individual needs to go to the post office periodically. This is eliminated in real life by introducing a mail delivery mechanism.
It is the same in a GUI system as shown below. Your business logic, in this case, the cassette player, will update all the GUI components periodically, just like a post man who comes to your house with mail. It would have been inefficient for the total system to implement a periodic check by each widget to get the progress.
There are two typical models for Observer based on the way data is passed. It can be a push model or a pull model. In the push model, data is pushed along with the notification. An example for this is mail delivery, magazine subscriptions etc. In the pull model, the client will be notified about what is happening. But, it is always the responsibility of the client to check whether the relevant data is there or not. An example for this is RSS feeds. Whenever there is a change in the website, and if you have subscribed for the feed, you will get a notification. But, it is up to you to go back and see if you are interested.
Factory Method and Abstract Factory design patterns are quite similar. How are they similar and how are they different?
Both of these patterns provide an interface where the subclasses don't know what type of object they want to create. Instead they use the factory which creates it for them. These are both creational design patterns because they provide an easy way for the user to make objects without having to worry about any details on why and how the object is to be made. They are different in that the Factory Method design produces a specific object and the Abstract Factory Method produces a family of objects which have to be casted down to the specific one you want. The Factory Method does more work for you and gives you exactly what you need, while the Abstract Factory gives you a general object and you have to decide what type of that object you want. In other words, the Abstract Factory gives you more flexibility, but more work, and the Factory Method, less felixibility and less work. Two common tradeoffs.
How are the Adapter and Bridge patterns similar and different?
Both of these design patterns recognize the difference between the interface and the implementation of that interface. This is the only similarity I can find, otherwise they are very different. The Bridge pattern is a behavioral pattern and it seperates the interface from the implementation. That is its primary goal. This allows for the interface and the implementation to change for every object. This is helpful in enviroments when it is essential to have many different types of views and many implementations in each. The slides talked about "windows" in operating systems which is a good example. The Adapter pattern, however, is a structural pattern and changes the normal interface of a class (how a class should look when using the code as a base), to an interface which is suitable for the user who will use your program. The adapter pattern brings up a good point that the way you implement your class doesn't necessary make a good basis for you UI structure. The adapter changes your implementation for you.
Basic similarity: Hard-coding the names of classes into your code is a very bad idea from a maintenance standpoint when those classes are often likely to differ based upon the context of the program. Both AbstractFactory and AbstractMethod realize the need keep instance creation of such classes from occuring inline. Thus, both delegate instance creation responsibility to someone else.
AbstractMethod delegates the responsibility to another method (in the same class). If a different class needs to be created, we simply use inheritance to override the default behavior. It keeps the decision between what class to create localized.
AbstractFactory, however, delegates responsibility to a different class whose sole responsibility is to create objects. All the objects the Factory can create are usually in the same family or are dependent upon each other. Again, how to create specific objects is defined by subclasses while how to put those pieces together may take on a general definition defined in the super, abstract class. AbstractFactory allows other classes to pick a Factory that has the Factory methods needed. AbstractFactory classes are also reusable.
with bridge we are seeing an abstraction of particular implementation. so we are taking away the details of the model and taking away the excess implementation code. not just hiding details, but separating, coexisting. and i see a very similar setup for adapter. Adapter has a target client domain and an source adaptee interface. This is very general, the target could be a computer made from helium. how do I transfer my JukeBox to a helium computer? well I just need to follow an Adapter design pattern? yes, the interface is wrapt up and reused! but what if we had a Bridge pattern for the JukeBox? then we can create an all new JukeBox based on the abstract JukeBox, but exploit a different computational model with the helium computer (in this imaginary world where helium computer model is unique from — silicon). perhaps my example is ridiculous - but the similarity is there, no? I place an emphasis on a cross-link from existing implementation/interface to abstraction/client/target. i hope the differences are clear, but I'll save them in case I'm already off the mark!
Similarities - provides an interface to the user to decide for the user the exact class to instantiate. both are creational design patterns.
Differences - Factory defines an interface for creating an object, but let subclasses decide which class to instantiate, while Abstract Factory provides an interface for creating families of related or dependent objects. In some sense, select a class which has the Factory methods you need. (straight from the lecture notes/extras/dc.ppt). Therefore, this means that the Abstract Factory provides a higher level of abstraction than the Factory method, and also might create more than one object in an instantiation.
b) Similarities - both are used to modify existing interfaces to meet requirements/expections.
Differences - Bridge is Behavioral. Bridge decouples an abstraction from its implementation so the two can vary independently. There's only one implementor in a Bridge design. Adaptor is Structural. Adaptor provides an interface around another interface so as to enable the interface to meet requirements/expectations. Provides the ability to alter classes conveniently.
Object Oriented Design Principles are core of OOPS programming but I have seen most of Java programmer chasing design patterns like Singleton pattern, Decorator pattern or Observer pattern but not putting enough attention on Object oriented analysis and design or following these design principles. I have regularly seen Java programmers and developers of various experience level who either doesn’t heard about these OOPS and SOLID design principle or simply doesn’t know what benefits a particular design principle offers or how to use these design principle in coding.
Bottom line is always strive for highly cohesive and loosely couple solution, code or design and looking open source code from Apache and Sun are good examples of Java design principles or how design principles should be used in Java coding. Java Development Kit follows several design principle like Factory Pattern in BorderFactory class, Singleton pattern in Runtime class and if you interested more on Java code read Effective Java by Joshua Bloch , a gem by the guy who wrote Java API. My another personal favorite on object oriented design pattern is Head First Design Pattern by Kathy Sierra and others and Head First Object Oriented Analysis and Design.
Though best way of learning design principles or pattern is real world example and understanding the consequences of violating that design principle, subject of this article is Introducing Object oriented design principles for Java Programmers who are either not exposed to it or in learning phase. I personally think each of these design principle need an article to explain it clearly and I will definitely try to do it here but for now just get yourself ready for quick bike ride on design principle town
Object oriented design principle 1 – DRY (Don’t repeat yourself)
As name suggest DRY (don’t repeat yourself) means don’t write duplicate code, instead use abstraction to abstract common things in one place. if you use a hardcoded value more than one time consider making it public final constant, if you have block of code in more than two place consider making it a separate method. Benefit of this SOLID design principle is in maintenance. Its worth to note is don’t abuse it, duplicate is not for code but for functionality means if you used common code to validate OrderID and SSN it doesn’t mean they are same or they will remain same in future. By using common code for two different functionality or thing you closely couple them forever and when your OrderID changes its format, your SSN validation code will break. So be aware of such coupling and just don’t combine anything which uses similar code but are not related.
Object oriented design principle 2 – Encapsulate what varies
Only one thing is constant in software field and that is “Change”, So encapsulate the code you expect or suspect to be changed in future. Benefit of this OOPS Design principle is that Its easy to test and maintain proper encapsulated code. If you are coding in Java then follow principle of making variable and methods private by default and increasing access step by step e.g. from private to protected and not public. Several of design pattern in Java uses Encapsulation, Factory design pattern is one example of Encapsulation which encapsulate object creation code and provides flexibility to introduce new product later with no impact on existing code.
Object oriented design principle 3 – Open Closed principle
Classes, methods or functions should be Open for extension (new functionality) and Closed for modification. This is another beautiful object oriented design principle which prevents some-one from changing already tried and tested code. Ideally if you are adding new functionality only than your code should be tested and that’s the goal of Open Closed Design principle.
Object oriented design principle 4 – Single Responsibility Principle (SRP)
There should not be more than one reason for a class to change or a class should always handle single functionality. If you put more than one functionality in one Class in Java it introduce coupling between two functionality and even if you change one functionality there is chance you broke coupled functionality which require another round of testing to avoid any surprise on production environment.
Object oriented design principle 5 – Dependency Injection or Inversion principle
Don’t ask for dependency it will be provided to you by framework. This has been very well implemented in Spring framework, beauty of this design principle is that any class which is injected by DI framework is easy to test with mock object and easier to maintain because object creation code is centralized in framework and client code is not littered with that.There are multiple ways to implemented Dependency injection like using byte code instrumentation which some AOP (Aspect Oriented programming) framework like AspectJ does or by using proxies just like used in Spring.
Object oriented design principle 6 – Favour Composition over Inheritance
Always favour composition over inheritance if possible. Some of you may argue this but I found that Composition is lot more flexible than Inheritance. Composition allows to change behaviour of a class at runtime by setting property during runtime and by using Interfaces to compose a class we use polymorphism which provides flexibility of to replace with better implementation any time. Even Effective Java advise to favor composition over inheritance.
Object oriented design principle 7 – Liskov Substitution Principle (LSP)
According to Liskov Substitution Principle Subtypes must be substitutable for super type i.e. methods or functions which uses super class type must be able to work with object of sub class without any issue”. LSP is closely related to Single responsibility principle and Interface Segregation Principle. If a class has more functionality than subclass might not support some of the functionality and does violated LSP. In order to follow LSP design principle, derived class or sub class must enhance functionality not reducing it.
Object oriented design principle 8 – Interface Segregation principle (ISP)
Interface Segregation Principle stats that a client should not implement an interface if it doesn’t use that. this happens mostly when one interface contains more than one functionality and client only need one functionality and not other.Interface design is tricky job because once you release your interface you can not change it without breaking all implementation. Another benefit of this desing principle in Java is, interface has disadvantage to implement all method before any class can use it so having single functionality means less method to implement.
Object oriented design principle 9 – Programming for Interface not implementation
Always program for interface and not for implementation this will lead to flexible code which can work with any new implementation of interface. So use interface type on variables, return types of method or argument type of methods in Java. This has been advised by many Java programmer including in Effective Java and head first design pattern book.
Object oriented design principle 10 – Delegation principle
Don’t do all stuff by yourself, delegate it to respective class. Classical example of delegation design principle is equals() and hashCode() method in Java. In order to compare two object for equality we ask class itself to do comparison instead of Client class doing that check. Benefit of this design principle is no duplication of code and pretty easy to modify behaviour.
All these object oriented design principle helps you write flexible and better code by striving high cohesion and low coupling. Theory is first step but what is most important is to develop ability to find out when and to apply these design principle and find our whether we are violating any design principle and compromising flexibility of code. but again as nothing is perfect in this world, don’t always try to solve problem with design patterns and design principle they are mostly for large enterprise project which has longer maintenance cycle.
Creational Patterns
Can be used to instantiate objects, directly or indirectly.
1. Abstract Factory: - Creates an instance of several families of classes. Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
2. Builder-: Separates object construction from its representation. Separate the construction of a complex object from its representation so that the same construction processes can create different representations.
3. Factory Method: - Creates an instance of several derived classes. Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
4. Prototype-: A fully initialized instance to be copied or cloned. Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
5. Singleton: - A class of which only a single instance can exist. Ensure a class only has one instance, and provide a global point of access to it.
Structural Patterns
it can be used to organize your program into groups.
This grouping will provide you clarity and will enable you for easier maintainability.
1. Adapter: - Match interfaces of different classes. Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
2. Bridge: - Separates an object’s interface from its implementation. Decouple an abstraction from its implementation so that the two can vary independently.
3. Composite: - A tree structure of simple and composite objects. Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
4. Decorator: - Add responsibilities to objects dynamically. Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality.
5. Facade: - A single class that represents an entire subsystem. Provide a unified interface to a set of interfaces in a system. Facade defines a higher-level interface that makes the subsystem easier to use.
6. Flyweight: - A fine-grained instance used for efficient sharing. Use sharing to support large numbers of fine-grained objects efficiently. A flyweight is a shared object that can be used in multiple contexts simultaneously. The flyweight acts as an independent object in each context it’s indistinguishable from an instance of the object that’s not shared.
7. Proxy: - An object is representing another object. Provide a surrogate or placeholder for another object to control access to it.
Behavioral Patterns
It can be used to define the communication and control flow between objects.
1. Chain of Resp: - A way of passing a request between a chain of objects. Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
2. Command: - Encapsulate a command request as an object. Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
3. Interpreter: - A way to include language elements in a program. Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
4. Iterator: - Sequentially access the elements of a collection. Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
5. Mediator: - Defines simplified communication between classes. Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
6. Memento: - Capture and restore an object's internal state. Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
7. Observer: - A way of notifying change to a number of classes. Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
8. State: -Alter an object's behavior when its state changes. Allow an object to alter its behavior when it’s internal state changes. The object will appear to change its class.
9. Strategy: - Encapsulates an algorithm inside a class. Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
10. Template: -Defer the exact steps of an algorithm to a subclass. Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing.
Software design principles represent a set of guidelines that helps us to avoid having a bad design.
Design patterns are used and supported extensively throughout the Java APIs. Here are some examples:
- The Model-View-Controller design pattern is used extensively throughout the Swing API.
- The getInstance() method in java.util.Calendar is an example of a simple form of the Factory Method design pattern.
- The classes java.lang.System and java.sql.DriverManager are examples of the Singleton pattern, although they are not implemented using the approach recommended in the GoF book but with static methods.
- The Prototype pattern is supported in Java through the clone() method defined in class Object and the use of java.lang.Cloneable interface to grant permission for cloning.
- The Java Swing classes support the Command pattern by providing an Action interface and an AbstractAction class.
- The Java 1.1 event model is based on the observer pattern. In addition, the interface java.util.Observable and the class java.util.Observer provide support for this pattern.
- The Adapter pattern is used extensively by the adapter classes in java.awt.event.
- The Proxy pattern is used extensively in the implementation of Java's Remote Method Invocation (RMI) and Interface Definition Language (IDL) features.
- The structure of Component and Container classes in java.awt provide a good example of the Composite pattern.
- The Bridge pattern can be found in the separation of the components in java.awt (e.g., Button and List), and their counterparts in java.awt.peer.
- Iterator pattern is supported through java.util.Enumeration and java.util.Iterator
- Command pattern is also used by the Swing Undo framework
- Singleton in used by java.lang.Runtime and java.awt.Toolkit
- The Decorator pattern is used by the I/O streams.
- Bridge Pattern is used for Drivers
- Strategy pattern use in Collection framework
There is also the whole underlying (overarching?) theme of MVC, where the JSP Pages represent the View, the FrontController/Helper classes and Session Beans the Control, and the Entity Beans the model.
• How will you design your Singleton Patten class to be thread-safe? (a standard interview question!) - Adding synchronized keyword to the getSingleton() method is inefficient solution. Initialize the static private Singleton object within Synchronized block. In this way you can achieve it.
• What Design Pattern can be used for classical Producer Consumer problem? (a simple question) - Use observer pattern (publisher subscriber model)
• M.S Word can store million lines of text. Each character in the text will have set of properties like font-color, font-size, font-style and etc. So, M.S Word application has to maintain a property structure for each and every character and that may lead to heavy storage. What design pattern will you apply to overcome this problem? - You have to create property group for each possible styles (font-size, font-color, font-face & etc). So, common characters will be part of a property group, there by reducing the storage of each character. This is called FlyWeight Pattern.
• Your application uses 1000 classes and they have interaction among each other. This will lead to complex communication across objects, so what design pattern can solve this problem? - Use Mediator pattern to separate the direct communication across objects.
• An application reads input from various clients in multiple stages and creates a binary tree structure out of all received inputs. Which design pattern can be used to design such application? - Building an object in multiple set - you call it Builder pattern! The realworld example is XSDBuilder class in Java.
• You have to design a budget management application for global users. But, have to provide an option to configure their native tax rules. Which design pattern, do you think, can solve this? - Use Template Pattern. It provides templates of methods and allowing you to override certain portion of logic.
• You have a core application class. But, you have to be able assign extra functionalities to the core class on the fly (at runtime). Which patterns deserves this purpose? - Decorator Pattern. This is similar to the pattern designed for java.io.* classes(BufferedReader, DataInputStream and etc.)
- Why we are using such huge code for suspending and resuming. Apart from that we can just use
while(){
initialize all thread..........
start the thread..
add in group...
}
........................
while(threadActivatedFlag )
{
if(threadGroup.activeCount()==0)
threadActivatedFlag = false;
else
Thread.sleep(4000);}
-----------------------------------------------------------------------------------------------------------------------------------------------
1. Write a Java program to create three threads namely A, B, C and make them run one after another. (C has to run after B completes, B has to run after A completes).
2. What happens when a thread calls notify() but no thread(s) is waiting?
3. How will you declare a timer variable that will be accessed by multiple threads very frequently?
4. How will you synchronize static variables?
5. What happens when threads are waiting, but never being notified?
1. Many ways to do it. I prefer join(). When a thrad A calls b.join(), then A runs only after thread b completes. So, for this problem, C has to call b.join() and B has to call a.join()
2. Actually…, nothing the notify() call simply returns.
3. Declare the variable as volatile. Every thread caches a copy of instance variable, work with local copy, and then sync it with master copy. But, threads do not cache a copy of volatile instance variable.
4. Obtain class level lock. synchronized( obj.getClass()) {……..}
5. Leaving the answer to readers!
-----------------------------------------------------------------------------------------------------------------------------------------------
1. You need to insert huge amount of objects and randomly delete them one by one. Which Collection data structure is best pet?
2. What goes wrong if the HashMap key has same hashCode value?
3. If hashCode() method is overridden but equals() is not, for the class ‘A’, then what may go wrong if you use this class as a key in HashMap?
4. How will you remove duplicate element from a List?
5. How will you synchronize a Collection class dynamically?
1. Obviously, LinkedList.
2. It leads to ‘Collision’ wherein all the values are stored in same bucket. Hence, the searching time increases quad radically.
3. Left to Readers.
4. Add the List elements to Set. Duplicates will be removed.
5. Use the utility method
-----------------------------------------------------------------------------------------------------------------------------------------------
Open Close Principle
"Software entities like classes, modules and functions should be open for extension but closed for modifications."
OPC is a generic principle. You can consider it when writing your classes to make sure that when you need to extend their behavior you don�t have to change the class but to extend it. The same principle can be applied for modules, packages, libraries. If you have a library containing a set of classes there are many reasons for which you�ll prefer to extend it without changing the code that was already written (backward compatibility, regression testing, �). This is why we have to make sure our modules follow Open Closed Principle.
When referring to the classes Open Close Principle can be ensured by use of Abstract Classes and concrete classes for implementing their behavior. This will enforce having Concrete Classes extending Abstract Classes instead of changing them. Some particular cases of this are Template Pattern and Strategy Pattern.
Dependency Inversion Principle
"High-level modules should not depend on low-level modules. Both should depend on abstractions."
"Abstractions should not depend on details. Details should depend on abstractions."
Dependency Inversion Principle states that we should decouple high level modules from low level modules, introducing an abstraction layer between the high level classes and low level classes. Further more it inverts the dependency: instead of writing our abstractions based on details, the we should write the details based on abstractions.
By applying the Dependency Inversion the modules can be easily changed by other modules just changing the dependency module. Factories and Abstract Factories can be used as dependency frameworks, but there are specialized frameworks for that, known as Inversion of Control Container.
Interface Segregation Principle
"Clients should not be forced to depend upon interfaces that they don't use."
For example if we create an interface called Worker and add a method lunch break, all the workers will have to implement it. What if the worker is a robot?
"As a conclusion Interfaces containing methods that are not specific to it are called polluted or fat interfaces. We should avoid them.
Reactor
Recently, I went to a restaurant in Bangalore. There was a female standing outside, receiving all the people entering the restaurant. She received us with a pleasant smile, then took us inside, and helped us find a table. She assigned a waiter to serve us, and then went back to the reception and waited for new clients. All she did was receive a new visitor. She is just like a web server serving multiple clients. In a typical web server, there is a thread simply waiting for requests from clients. Whenever there is a client request, it creates a separate thread and assigns that thread to handle the request. The thread will die down after serving the requests.
Facade
Imagine you want to organize a marriage reception. You need to decorate the hall where the event is planned. You need a music band to play some music. You want to organize dinner for say 100 people, and also snack in the evening for around 50 people. If you wanted to organize such an event some 10 years back, you wanted to go to a caterer for food, a musical troop for music, and organize flowers and people to decorate them, and so and so. Some twenty years back, we needed to go to the fish market, the meat shop, the vegetable market etc., for the raw materials for the food and then organize a cook so that you have everything ready for the event. Now, life is really simpler with event managers. You just need to walk to an event manager and tell him that you need a hall decorated with flowers, dinner for 100 people, snacks for 50 people, and need a good music troop to play music while the reception is going on. You don’t need to worry about anything, and they will take care of the rest. This is a typical example for Façade. You don’t need to interact with many different objects for each and every activity. You will be provided a single interface which will act as a façade for many activities. This makes the life of clients much simpler.
Other examples for Facade are one stop bill payment shops, a support desk in a big organization which takes all kinds of support requests etc.
Decorator
A decorator decorates something. An example for Decorator is a sunglass. It takes light as input, removes all harmful parts in the light, and passes it on. If you give apple as an input to a system, and if it gives orange as output, that is not a Decorator. Another example for this is music filtering.
A software example for Decorator is JAVA I/O. Initially, I wondered why we need to create so many objects just to do a file operation. I realized how flexible and wonderful it is after some time.
Template
A typical example for the Template pattern is the Computer Engineering degree curriculum. It covers all the basic stuff required for a typical software engineer. He can’t work as it is in an industry as he needs to fill in many gaps which are required in the specific domain. But, he will have the necessary knowledge to move to any software company after completion of the course.
Adapter
I think this is a self explanatory pattern. You can find many real life examples for this pattern, and the simplest, which is called by the same name, is a power adapter. You have an AC power supply and the responsibility of the adapter is to provide different types of sockets adapted to the one needed.
Another example for this is a translator who is translating languages spoken by one person for another person.
Factory Pattern and Abstract Factory pattern
Imagine you are constructing a house and you approach a carpenter for a door. You give the measurement for the door and your requirements, and he will construct a door for you. In this case, the carpenter is a factory of doors. Your specifications are inputs for the factory, and the door is the output or product from the factory.
Now, consider the same example of the door. You can go to a carpenter, or you can go to a plastic door shop or a PVC shop. All of them are door factories. Based on the situation, you decide what kind of factory you need to approach. This is like an Abstract Factory.
Observer pattern
A typical example for the Observer pattern is the conventional mail delivery system. Whenever you have a mail, the postman will come and knock at your door with the mail. Just imagine if you have to go to the post office every day and check whether there are any mails. It would have been a really inefficient system as each individual needs to go to the post office periodically. This is eliminated in real life by introducing a mail delivery mechanism.
It is the same in a GUI system as shown below. Your business logic, in this case, the cassette player, will update all the GUI components periodically, just like a post man who comes to your house with mail. It would have been inefficient for the total system to implement a periodic check by each widget to get the progress.
There are two typical models for Observer based on the way data is passed. It can be a push model or a pull model. In the push model, data is pushed along with the notification. An example for this is mail delivery, magazine subscriptions etc. In the pull model, the client will be notified about what is happening. But, it is always the responsibility of the client to check whether the relevant data is there or not. An example for this is RSS feeds. Whenever there is a change in the website, and if you have subscribed for the feed, you will get a notification. But, it is up to you to go back and see if you are interested.
Factory Method and Abstract Factory design patterns are quite similar. How are they similar and how are they different?
Both of these patterns provide an interface where the subclasses don't know what type of object they want to create. Instead they use the factory which creates it for them. These are both creational design patterns because they provide an easy way for the user to make objects without having to worry about any details on why and how the object is to be made. They are different in that the Factory Method design produces a specific object and the Abstract Factory Method produces a family of objects which have to be casted down to the specific one you want. The Factory Method does more work for you and gives you exactly what you need, while the Abstract Factory gives you a general object and you have to decide what type of that object you want. In other words, the Abstract Factory gives you more flexibility, but more work, and the Factory Method, less felixibility and less work. Two common tradeoffs.
How are the Adapter and Bridge patterns similar and different?
Both of these design patterns recognize the difference between the interface and the implementation of that interface. This is the only similarity I can find, otherwise they are very different. The Bridge pattern is a behavioral pattern and it seperates the interface from the implementation. That is its primary goal. This allows for the interface and the implementation to change for every object. This is helpful in enviroments when it is essential to have many different types of views and many implementations in each. The slides talked about "windows" in operating systems which is a good example. The Adapter pattern, however, is a structural pattern and changes the normal interface of a class (how a class should look when using the code as a base), to an interface which is suitable for the user who will use your program. The adapter pattern brings up a good point that the way you implement your class doesn't necessary make a good basis for you UI structure. The adapter changes your implementation for you.
Basic similarity: Hard-coding the names of classes into your code is a very bad idea from a maintenance standpoint when those classes are often likely to differ based upon the context of the program. Both AbstractFactory and AbstractMethod realize the need keep instance creation of such classes from occuring inline. Thus, both delegate instance creation responsibility to someone else.
AbstractMethod delegates the responsibility to another method (in the same class). If a different class needs to be created, we simply use inheritance to override the default behavior. It keeps the decision between what class to create localized.
AbstractFactory, however, delegates responsibility to a different class whose sole responsibility is to create objects. All the objects the Factory can create are usually in the same family or are dependent upon each other. Again, how to create specific objects is defined by subclasses while how to put those pieces together may take on a general definition defined in the super, abstract class. AbstractFactory allows other classes to pick a Factory that has the Factory methods needed. AbstractFactory classes are also reusable.
with bridge we are seeing an abstraction of particular implementation. so we are taking away the details of the model and taking away the excess implementation code. not just hiding details, but separating, coexisting. and i see a very similar setup for adapter. Adapter has a target client domain and an source adaptee interface. This is very general, the target could be a computer made from helium. how do I transfer my JukeBox to a helium computer? well I just need to follow an Adapter design pattern? yes, the interface is wrapt up and reused! but what if we had a Bridge pattern for the JukeBox? then we can create an all new JukeBox based on the abstract JukeBox, but exploit a different computational model with the helium computer (in this imaginary world where helium computer model is unique from — silicon). perhaps my example is ridiculous - but the similarity is there, no? I place an emphasis on a cross-link from existing implementation/interface to abstraction/client/target. i hope the differences are clear, but I'll save them in case I'm already off the mark!
Similarities - provides an interface to the user to decide for the user the exact class to instantiate. both are creational design patterns.
Differences - Factory defines an interface for creating an object, but let subclasses decide which class to instantiate, while Abstract Factory provides an interface for creating families of related or dependent objects. In some sense, select a class which has the Factory methods you need. (straight from the lecture notes/extras/dc.ppt). Therefore, this means that the Abstract Factory provides a higher level of abstraction than the Factory method, and also might create more than one object in an instantiation.
b) Similarities - both are used to modify existing interfaces to meet requirements/expections.
Differences - Bridge is Behavioral. Bridge decouples an abstraction from its implementation so the two can vary independently. There's only one implementor in a Bridge design. Adaptor is Structural. Adaptor provides an interface around another interface so as to enable the interface to meet requirements/expectations. Provides the ability to alter classes conveniently.