Aoop Exp3
Aoop Exp3
Aim/Objective: To analyse the implementation of Adapter Design Patterns for the real-time scenario.
Description:
The student will understand the concept of Adapter Design Patterns.
Pre-Requisites:
Knowledge: Classes and Objects in JAVA
Tools: Eclipse IDE for Enterprise Java and Web Developers
Pre-Lab:
1. Draw the UML Relationship Diagram for Adapter Design Pattern for Mobile charger adapter scenario. Note:
Mobile battery needs 3 volts to charge but the normal socket produces either 120V (US) or 240V (India). So
the mobile charger works as an adapter between mobile charging socket and the wall socket.
Ans: -
2. State about Structural Design Pattern with example and list all the types of Structural Design Pattern
Ans:
Structural Design Patterns focus on organizing classes and objects to create larger, flexible structures.
They simplify relationships between components and enhance code reuse.
1. Adapter Pattern: Allows incompatible interfaces to work together by providing a bridge between them.
2. Bridge Pattern: Decouples abstraction from implementation, allowing them to vary independently.
3. Composite Pattern: Represents objects in a tree-like structure, treating individual and grouped objects
uniformly.
4. Decorator Pattern: Dynamically adds new functionality to objects by wrapping them with decorator
objects.
5. Facade Pattern: Provides a simple interface to a complex system, making it easier to use.
6. Flyweight Pattern: Minimizes memory usage by sharing data between multiple objects.
7. Proxy Pattern: Acts as a substitute for another object, controlling access to it.
These patterns promote better organization, flexibility, and modularity in software systems.
In-Lab:
• Procedure/Program:
package factorypattern;
public class AdapterPatternDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
interface MediaPlayer {
void play(String audioType, String fileName);
}
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
// inbuilt support to play mp3 music files
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file. Name: " + fileName);
} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media. " + audioType + " format not supported");
}
}
}
class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
@Override
public void playMp4(String fileName) {
// Do Nothing
}
}
class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// Do Nothing
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
}
class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
Data and Results:
The code implements the adapter pattern to allow an AudioPlayer to play files that are not supported by it natively.
The MediaAdapter class acts as an adapter between the AudioPlayer and the AdvancedMediaPlayer classes. It
translates the requests from the AudioPlayer to the AdvancedMediaPlayer so that the AudioPlayer can play files that
are not supported by it natively.
The code is well-organized and easy to understand. The classes are well-named and the code is well-commented.
The code is efficient. The MediaAdapter class uses polymorphism to avoid code duplication.
The code is reusable. The MediaAdapter class can be used to adapt any class to a new interface.
The Adapter Pattern allows objects with different or incompatible interfaces to work together by providing a
middleman called the "Adapter." The Adapter translates requests from the client code into a format that the
incompatible object (Adaptee) can understand. It also translates the responses from the Adaptee back into a
format that the client code can understand. This way, the objects with incompatible interfaces can collaborate
seamlessly through the Adapter.
2. Discuss about Adapter Pattern by considering the scenario of a USB to Ethernet adapter
Ans:
Imagine you have a computer with only USB ports, but you need to connect it to the internet using an Ethernet
cable, which has a different plug. You can't connect them directly because of the interface mismatch.
To make them work together, you use a USB to Ethernet adapter. This adapter acts as a bridge between the
computer's USB port and the Ethernet cable.
The Adapter Pattern allows the USB port (client) and the Ethernet cable (Adaptee) to collaborate seamlessly.
The adapter translates the requests and data between the two, making them compatible and allowing you to
connect to the internet through your USB port.
1. Class Adapter:
- In the Class Adapter pattern, adaptation is achieved by inheriting from both the target interface and
the Adaptee class.
- The Adapter class becomes a subclass of the Adaptee, which means it inherits its behavior and
attributes.
- At the same time, the Adapter class also implements the target interface, providing the necessary
adaptation.
- This pattern requires multiple inheritance, which may not be supported in all programming languages.
2. Object Adapter:
- In the Object Adapter pattern, adaptation is achieved by composing an instance of the Adaptee class
within the Adapter class.
- The Adapter class holds a reference to the Adaptee object and delegates the requests to it, rather than
inheriting its behavior.
- The Adapter class also implements the target interface, just like in the Class Adapter pattern.
- This pattern uses object composition, making it more flexible and adaptable. It can work with different
Adaptee classes without changing the Adapter's structure.
In summary, the Class Adapter uses inheritance to adapt the Adaptee's interface to the target interface,
while the Object Adapter uses composition to achieve the same adaptation. The Object Adapter is often
considered more flexible and preferred in many scenarios as it allows for easier swapping of different
Adaptee implementations without changing the Adapter itself.
4. Which design problems does the adapter design pattern solve?
Ans: -
In a simple way, the Adapter Design Pattern solves the problem of making two classes or components
work together when they have incompatible interfaces. It acts as a bridge, allowing objects with different
interfaces to collaborate by providing a common interface that both can understand. This way, the Adapter
Pattern helps in seamless communication and interaction between incompatible components in a system.
Ans: -
Certainly! Here's a simple form of the pros and cons of the Adapter Design Pattern:
Pros:
1. Resolves Interface Incompatibility: Helps objects with different interfaces collaborate, promoting code
reuse.
Cons:
1. Increased Complexity: Introduces an additional layer of abstraction, potentially making the code more
complex.
2. Potential Performance Overhead: Adapter may incur overhead due to translation and adaptation logic.
3. Multiple Adapters: In scenarios with many Adaptees, multiple adapters may be needed, leading to
increased code complexity.
Post-Lab:
Procedure/Program:
interface AdvancedImageViewer {
void showPng();
void showJpg();
}
class PngShower implements AdvancedImageViewer {
@Override
public void showPng() {
System.out.println("Showing png image");
}
@Override
public void showJpg() {
// Do nothing
}
}
class JpgShower implements AdvancedImageViewer {
@Override
public void showPng() {
// Do nothing
}
@Override
public void showJpg() {
System.out.println("Showing jpg image");
}
}
class ImageAdapter implements AdvancedImageViewer {
private PngShower pngShower;
private JpgShower jpgShower;
public ImageAdapter() {
pngShower = new PngShower();
jpgShower = new JpgShower();
}
@Override
public void showPng() {
pngShower.showPng();
}
@Override
public void showJpg() {
jpgShower.showJpg();
}
}
public class AdapterPatternExp3 {
public static void main(String[] args) {
ImageAdapter imageAdapter = new ImageAdapter();
imageAdapter.showPng();
imageAdapter.showJpg();
}
}