0% found this document useful (0 votes)
33 views42 pages

Pandit Deendayal Energy University School of Technology: 21BCP430D Pranjal M. Patel

The document is a lab manual for a course on design patterns. It provides examples and code for the Adapter and Composite structural design patterns. The Adapter pattern code shows how to adapt an advanced media player interface to a generic media player interface. The Composite pattern code shows how to create a hierarchical tree structure of computer parts with individual parts as leaves and composite groups of parts as branches.

Uploaded by

Devasya Patel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views42 pages

Pandit Deendayal Energy University School of Technology: 21BCP430D Pranjal M. Patel

The document is a lab manual for a course on design patterns. It provides examples and code for the Adapter and Composite structural design patterns. The Adapter pattern code shows how to adapt an advanced media player interface to a generic media player interface. The Composite pattern code shows how to create a hierarchical tree structure of computer parts with individual parts as leaves and composite groups of parts as branches.

Uploaded by

Devasya Patel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

21BCP430D Pranjal M.

Patel

PANDIT DEENDAYAL ENERGY UNIVERSITY


SCHOOL OF TECHNOLOGY

Course: Design Pattern & Thinking Lab


Course Code: 20CP210P
LAB MANUAL
B.Tech. (Computer Science and Engineering)
Semester 4

Submitted To: Submitted By:

Pranjal M. Patel

21BCP430D

G2 batch
21BCP430D Pranjal M. Patel

STRUCTURAL DESIGN PATTERN

1. Adapter Pattern:

 Introduction:
Adapter pattern works as a bridge between two incompatible interfaces. This
type of design pattern comes under structural pattern as this pattern combines
the capability of two independent interfaces.
This pattern involves a single class which is responsible to join functionalities
of independent or incompatible interfaces. A real life example could be a case
of card reader which acts as an adapter between memory card and a laptop.
You plugin the memory card into card reader and card reader into the laptop
so that memory card can be read via laptop.

 Diagram:
21BCP430D Pranjal M. Patel

EXAMPLE-1:
 Code:
 mediaplayer.java
package Adapter1;

public interface MediaPlayer


{
public void play(String audioType, String fileName);
}

 AdvancedMediaPlayer.java
package Adapter1;

public interface AdvancedMediaPlayer


{
public void playVlc(String fileName);
public void playMp4(String fileName);
}

 VlcPlayer.java
package Adapter1;

public 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
}
}
21BCP430D Pranjal M. Patel

 Mp4Player.java
package Adapter1;

public 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);
}
}

 MediaAdapter.java
package Adapter1;

public 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")){
21BCP430D Pranjal M. Patel

advancedMusicPlayer.playMp4(fileName);
}
}
}

 AudioPlayer.java
package Adapter1;

public 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);

//mediaAdapter is providing support to play other file formats

else if(audioType.equalsIgnoreCase("vlc") ||
audioType.equalsIgnoreCase("mp4")){

mediaAdapter = new MediaAdapter(audioType);

mediaAdapter.play(audioType, fileName);

else{
21BCP430D Pranjal M. Patel

System.out.println("Invalid media. " + audioType + " format not


supported");

 AdapterPatternDemo.java
package Adapter1;

public class AdapterPatternDemo {

public static void main(String[] args) {

AudioPlayer audioPlayer = new AudioPlayer();

audioPlayer.play("mp3", "Summertime Sadness.mp3");

audioPlayer.play("mp4", "HeartLess.mp4");

audioPlayer.play("vlc", "Disaster.vlc");

audioPlayer.play("avi", "Lonely.avi");

 Output:
21BCP430D Pranjal M. Patel

EXAMPLE-2:
 Code:
 ImageViewer.java
package Adapter2;

public interface ImageViewer


{
public void show(String imageFormat, String fileName);
}

 AdvancedImageViewer.java
package Adapter2;

public interface AdvancedImageViewer


{
public void showPng(String fileName);
public void showJpg(String fileName);
}

 PngShower.java
package Adapter2;

public class PngShower implements AdvancedImageViewer


{
@Override
public void showPng(String fileName)
{
System.out.println("It is showing 'png' file. File Name: "+ fileName);

@Override
public void showJpg(String fileName)
{
//do nothing in jpeg format
}
}
21BCP430D Pranjal M. Patel

 JpgShower.java
package Adapter2;

public class JpgShower implements AdvancedImageViewer


{

@Override
public void showPng(String fileName)
{
//do nothing in png format
}

@Override
public void showJpg(String fileName)
{
System.out.println("It is showing 'jpg' file. File Name: "+ fileName);

}
}

 ImageAdapter.java
package Adapter2;

public class ImageAdapter implements ImageViewer


{

AdvancedImageViewer advancedImageViewer;

public ImageAdapter(String imageFormat)


{

if(imageFormat.equalsIgnoreCase("png") )
{
advancedImageViewer = new PngShower();
}
else if (imageFormat.equalsIgnoreCase("jpg"))
{
advancedImageViewer = new JpgShower();
}
}

@Override
public void show(String imageFormat, String fileName)
21BCP430D Pranjal M. Patel

if(imageFormat.equalsIgnoreCase("png"))
{
advancedImageViewer.showPng(fileName);
}
else if(imageFormat.equalsIgnoreCase("jpg"))
{
advancedImageViewer.showJpg(fileName);
}
}
}

 GalleryApp.java
package Adapter2;

public class GalleryApp implements ImageViewer


{

ImageAdapter imageAdapter;

@Override
public void show(String imageFormat, String fileName)
{

if(imageFormat.equalsIgnoreCase("jpeg"))
{
System.out.println("Showing jpeg file. Name: " + fileName);

}
//imageAdapter is providing support to show other file formats
else if(imageFormat.equalsIgnoreCase("png") ||
imageFormat.equalsIgnoreCase("jpg"))
{
imageAdapter = new ImageAdapter(imageFormat);
imageAdapter.show(imageFormat, fileName);
}
else
{
System.out.println("Invalid image format. " + imageFormat + "
format is not supported");
}
}
21BCP430D Pranjal M. Patel

 AdapterPatternDemo.java
package Adapter2;

public class AdapterPatternDemo


{
public static void main(String[] args)
{

GalleryApp gallery = new GalleryApp();

gallery.show("jpeg", "Yagni.jpeg");
gallery.show("png", "Kashish.png");
gallery.show("jpeg", "Pranjal.jpeg");
gallery.show("tiff", "Vrushi.tiff");
}
}

 Output:
21BCP430D Pranjal M. Patel

2. Composite Pattern:

 Introduction:
Composite pattern is used where we need to treat a group of objects in similar
way as a single object. Composite pattern composes objects in term of a tree
structure to represent part as well as whole hierarchy. This type of design
pattern comes under structural pattern as this pattern creates a tree structure of
group of objects.
This pattern creates a class that contains group of its own objects. This class
provides ways to modify its group of same objects.

 Diagram:
21BCP430D Pranjal M. Patel

EXAMPLE-1:
 Code:
 ComputerPart.java
package sdp1;
//import java.util.List;

import java.util.*;

interface component
{
void showprice();
}
class leaf implements component
{
int price;
String name;

public leaf (int price,String name)


{
this.price = price;
this.name = name;
}

@Override
public void showprice() {

System.out.println(name);
System.out.println(price);
}
}

class composite implements component


{
String name;
List<component> components=new ArrayList<component>();

public composite(String name)


{
this.name = name;
}
21BCP430D Pranjal M. Patel

public void addcomponent(component com)


{
components.add(com);

public void showprice()


{
System.out.println(name);
for (component c: components)
{
c.showprice();
}

public class ComputerPart


{
}

 CompositeTest.java
package sdp1;

public class CompositeTest


{
public static void main (String[] args)
{
component hd=new leaf(5000,"harddrive");
component mouse=new leaf(700,"Mouse");
component monitor=new leaf(10000,"Monitor");
component ram=new leaf(3500,"ram");
component cpu=new leaf(8000,"cpu");
composite ph=new composite("peri");
composite cabinet=new composite("cabinet");
composite mb=new composite("Motherboard");
composite computer=new composite("Computer");

mb.addcomponent(cpu);
mb.addcomponent(ram);

ph.addcomponent(mouse);
21BCP430D Pranjal M. Patel

ph.addcomponent(monitor);

cabinet.addcomponent(hd);
cabinet.addcomponent(mb);

computer.addcomponent(ph);
computer.addcomponent(cabinet);

ram.showprice();
mb.showprice();
computer.showprice();

 Output:
21BCP430D Pranjal M. Patel

EXAMPLE-2:
 Code:
 Employee.java
package sdp2;

import java.util.ArrayList;
import java.util.List;

public class Employee {


private String name;
private String dept;
private int salary;
private List<Employee> subordinates;

// constructor
public Employee(String name,String dept, int sal) {
this.name = name;
this.dept = dept;
this.salary = sal;
subordinates = new ArrayList<Employee>();
}

public void add(Employee e) {


subordinates.add(e);
}

public void remove(Employee e) {


subordinates.remove(e);
}

public List<Employee> getSubordinates(){


return subordinates;
}

public String toString(){


21BCP430D Pranjal M. Patel

return ("Employee :[ Name : " + name + ", dept : " + dept + ",
salary :" + salary+" ]");
}
}

 CompositePatternDemo.java
package sdp2;

public class CompositePatternDemo {


public static void main(String[] args) {

Employee CEO = new Employee("Pranjal","CEO", 30000);

Employee headSales = new Employee("Yagni","Head


Sales", 20000);

Employee headMarketing = new Employee("Vrushi","Head


Marketing", 20000);

Employee clerk1 = new Employee("Katherine","Marketing",


10000);
Employee clerk2 = new Employee("Kashish","Marketing",
10000);

Employee salesExecutive1 = new


Employee("Betty","Sales", 10000);
Employee salesExecutive2 = new
Employee("Kashish","Sales", 10000);

CEO.add(headSales);
CEO.add(headMarketing);

headSales.add(salesExecutive1);
headSales.add(salesExecutive2);

headMarketing.add(clerk1);
headMarketing.add(clerk2);
21BCP430D Pranjal M. Patel

//print all employees of the organization


System.out.println(CEO);

for (Employee headEmployee : CEO.getSubordinates()) {


System.out.println(headEmployee);

for (Employee employee :


headEmployee.getSubordinates()) {
System.out.println(employee);
}
}
}
}

 Output:
21BCP430D Pranjal M. Patel

3. Decorator Pattern:
 Introduction:
Decorator pattern allows a user to add new functionality to an existing object
without altering its structure. This type of design pattern comes under structural
pattern as this pattern acts as a wrapper to existing class.
This pattern creates a decorator class which wraps the original class and
provides additional functionality keeping class methods signature intact.

 Diagram:
21BCP430D Pranjal M. Patel

EXAMPLE-1:
 Code:
 Shape.java
package Decorator1;

public interface Shape


{
void draw();
}

 Rctangle.java
package Decorator1;

public class Rectangle implements Shape


{

@Override
public void draw()
{
System.out.println("Shape: Rectangle");
}
}

 Circle.java
package Decorator1;

public class Circle implements Shape


{

@Override
public void draw()
{
System.out.println("Shape: Circle");
}
}
21BCP430D Pranjal M. Patel

 ShapeDecorator.java
package Decorator1;

public abstract class ShapeDecorator implements Shape


{
protected Shape decoratedShape;

public ShapeDecorator(Shape decoratedShape)


{
this.decoratedShape = decoratedShape;
}

public void draw()


{
decoratedShape.draw();
}
}

 RedShapeDecorator.java
package Decorator1;

public class RedShapeDecorator extends ShapeDecorator


{

public RedShapeDecorator(Shape decoratedShape)


{
super(decoratedShape);
}

@Override
public void draw()
{
decoratedShape.draw();
setRedBorder(decoratedShape);
}

private void setRedBorder(Shape decoratedShape)


21BCP430D Pranjal M. Patel

{
System.out.println("Border Color: Red");
}
}

 DecoratorPatternDemo.java
package Decorator1;

public class DecoratorPatternDemo


{
public static void main(String[] args)
{
Shape circle = new Circle();

Shape redCircle = new RedShapeDecorator(new Circle());

Shape redRectangle = new RedShapeDecorator(new


Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle with red border");
redCircle.draw();
System.out.println("\nRectangle with red border");
redRectangle.draw();
}
}

 Output:
21BCP430D Pranjal M. Patel

EXAMPLE-2:
 Code:
 Sandwich.java
package Decorator2;

public class SandwichMaker


{
public static void main(String args[])
{
Sandwich mySandwich = new WhiteBreadSandWich("White
bread Sandwich");
System.out.printf("Price of %s is $%.2f %n",
mySandwich.getDescription(), mySandwich.price());

//adding extra cheese using Decorator Patttern


mySandwich = new CheeseDecorator(mySandwich);
System.out.printf("Price of %s is $%.2f %n",
mySandwich.getDescription(), mySandwich.price());
}
}

 WhiteBreadSandWich.java
package Decorator2;

import java.math.BigDecimal;

public class WhiteBreadSandWich extends Sandwich


{
public WhiteBreadSandWich(String desc)
{
description = desc;
}

@Override
public BigDecimal price()
{
21BCP430D Pranjal M. Patel

return new BigDecimal("5.0");


}
}

 SandWichDecorator.java
package Decorator2;

import java.math.BigDecimal;

public abstract class SandWichDecorator extends Sandwich


{
@Override
public abstract BigDecimal price();
}

 CheeseDecorator.java
package Decorator2;

import java.math.BigDecimal;

public class CheeseDecorator extends SandWichDecorator


{
Sandwich currentSandwich;
public CheeseDecorator(Sandwich sw)
{
currentSandwich = sw;
}

@Override
public String getDescription()
{
return currentSandwich.getDescription() + ", Cheese";
}

@Override
public BigDecimal price()
{
21BCP430D Pranjal M. Patel

return currentSandwich.price().add(new
BigDecimal("1.50"));
}
}

 SandwichMaker.java
package Decorator2;

public class SandwichMaker


{
public static void main(String args[])
{
Sandwich mySandwich = new WhiteBreadSandWich("White
bread Sandwich");
System.out.printf("Price of %s is $%.2f %n",
mySandwich.getDescription(), mySandwich.price());

//adding extra cheese using Decorator Patttern


mySandwich = new CheeseDecorator(mySandwich);
System.out.printf("Price of %s is $%.2f %n",
mySandwich.getDescription(), mySandwich.price());
}
}

 Output:
21BCP430D Pranjal M. Patel

4. Facade Pattern:

 Introduction:
Facade pattern hides the complexities of the system and provides an interface
to the client using which the client can access the system. This type of design
pattern comes under structural pattern as this pattern adds an interface to
existing system to hide its complexities.
This pattern involves a single class which provides simplified methods
required by client and delegates calls to methods of existing system classes.

 Diagram:
21BCP430D Pranjal M. Patel

EXAMPLE-1:
 Code:
 Shape.java
package facade1;

public interface Shape


{
void draw();
}

 Rectangle.java
package facade1;

public class Rectangle implements Shape {

@Override
public void draw() {
System.out.println("Rectangle::draw()");
}
}

 Square.java
package facade1;

public class Square implements Shape {

@Override
public void draw() {
System.out.println("Square::draw()");
}
}
21BCP430D Pranjal M. Patel

 Circle.java
package facade1;

public class Circle implements Shape {

@Override
public void draw() {
System.out.println("Circle::draw()");
}
}

 ShapeMaker.java
package facade1;

public class ShapeMaker {


private Shape circle;
private Shape rectangle;
private Shape square;

public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}

public void drawCircle(){


circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
public void drawSquare(){
square.draw();
}
}
21BCP430D Pranjal M. Patel

 FacadePatternDemo.java
package facade1;

public class FacadePatternDemo {


public static void main(String[] args) {
ShapeMaker shapeMaker = new ShapeMaker();

shapeMaker.drawCircle();
shapeMaker.drawRectangle();
shapeMaker.drawSquare();
}
}

 Output:
21BCP430D Pranjal M. Patel

EXAMPLE-2:
 Code:
 Food.java
package facade;

public interface Food


{
public void prepareFood(String itemsRequired);
public String deliverFood();
}

 Pizza.java
package facade;
public class Pizza implements Food{
public String prepareItem;
public void prepareFood(String itemRequired)
{
prepareItem = "This pizza contains: " + itemRequired;
}
public String deliverFood() {
return prepareItem;
}
}
21BCP430D Pranjal M. Patel

 Pasta.java
package facade;
public class Pasta implements Food
{
public String prepareItem;
public void prepareFood(String itemRequired)
{
prepareItem = "This pasta contains: " + itemRequired;
}
public String deliverFood()
{
return prepareItem;
}
}

 Waiter.java
package facade;
public class Waiter {
public static String deliverFood (String foodType){
Ingredients ingredients = new Ingredients();
switch(foodType)
{
case "pizza":
Food pizza = new Pizza();
21BCP430D Pranjal M. Patel

String pizzaItem = ingredients.getPizzaItem();


pizza.prepareFood(pizzaItem);
return pizza.deliverFood();
case "pasta":
Food pasta = new Pasta();
String pastaItem = ingredients.getPastaItem();
pasta.prepareFood(pastaItem);
return pasta.deliverFood();
}
return foodType;
}
public static char[] deliverFood(FoodType pasta) {
// TODO Auto-generated method stub
return null;
}
}

 FoodType.java
package facade;

public enum FoodType {


PIZZA,
PASTA
}
21BCP430D Pranjal M. Patel

 Customer.java
package facade;

class Customer
{
public static void main(String args[])
{
Ingredients ingredients = new Ingredients();
//without facade
System.out.println("------Without Facade-------");
Food pizza = new Pizza();
pizza.prepareFood(ingredients.getPizzaItem());
System.out.println(pizza.deliverFood());

Food pasta = new Pasta();


pasta.prepareFood(ingredients.getPastaItem());
System.out.println(pasta.deliverFood());

System.out.println("------With Facade-------");
System.out.println(Waiter.deliverFood(FoodType.PASTA));
System.out.println(Waiter.deliverFood(FoodType.PIZZA));
}
}

 Output:
21BCP430D Pranjal M. Patel

5. Flyweight Pattern:

 Introduction:
Flyweight pattern is primarily used to reduce the number of objects created and
to decrease memory footprint and increase performance. This type of design
pattern comes under structural pattern as this pattern provides ways to decrease
object count thus improving the object structure of application.
Flyweight pattern tries to reuse already existing similar kind objects by storing
them and creates new object when no matching object is found.

 Diagram:
21BCP430D Pranjal M. Patel

EXAMPLE-1:
 Code:
 Shape.java
package Fp1;

public interface Shape


{
void draw();
}

 Circle.java
package Fp1;

public class Circle implements Shape


{
private String color;
private int x;
private int y;
private int radius;

public Circle(String color){


this.color = color;
}

public void setX(int x) {


this.x = x;
}

public void setY(int y) {


this.y = y;
}

public void setRadius(int radius) {


this.radius = radius;
}
21BCP430D Pranjal M. Patel

@Override
public void draw() {
System.out.println("Circle: Draw() [Color : " + color + ", x :
" + x + ", y :" + y + ", radius :" + radius);
}
}

 ShapeFactory.java
package Fp1;

import java.util.HashMap;

public class ShapeFactory


{

private static final HashMap circleMap = new HashMap();

public static Shape getCircle(String color)


{
Circle circle = (Circle)circleMap.get(color);

if(circle == null)
{
circle = new Circle(color);
circleMap.put(color, circle);
System.out.println("Creating circle of color : " + color);
}
return circle;
}
}
21BCP430D Pranjal M. Patel

 FlyweightPatternDemo.java
package Fp1;

public class FlyweightPatternDemo


{
private static final String colors[] = { "Blue", "Red", "Black",
"Green", "White" };
public static void main(String[] args)
{

for(int i=0; i < 20; ++i)


{
Circle circle =
(Circle)ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();
}
}
private static String getRandomColor()
{
return colors[(int)(Math.random()*colors.length)];
}
private static int getRandomX()
{
return (int)(Math.random()*100 );
}
private static int getRandomY()
{
return (int)(Math.random()*100);
}
}
21BCP430D Pranjal M. Patel

 Output:
21BCP430D Pranjal M. Patel

EXAMPLE-2:
 Code:
 Pen.java
package Fp2;

public interface Pen


{
public void setColor(String color);
public void draw(String content);
}

 BrushSize.java
package Fp2;

public enum BrushSize


{
THIN, MEDIUM, THICK
}

 ThickPen.java
package Fp2;

public class ThickPen implements Pen {

final BrushSize brushSize = BrushSize.THICK; //intrinsic


state - shareable
private String color = null; //extrinsic state - supplied by
client

public void setColor(String color) {


this.color = color;
}

@Override
public void draw(String content) {
21BCP430D Pranjal M. Patel

System.out.println("Drawing THICK content in color : " +


color);
}
}

 ThinPen.java
package Fp2;

public class ThinPen implements Pen {

final BrushSize brushSize = BrushSize.THIN;


private String color = null;

public void setColor(String color) {


this.color = color;
}

@Override
public void draw(String content) {
System.out.println("Drawing THIN content in color : " +
color);
}
}
 MediumPen.java
package Fp2;

public class MediumPen implements Pen {

final BrushSize brushSize = BrushSize.MEDIUM;


private String color = null;

public void setColor(String color) {


this.color = color;
}

@Override
public void draw(String content) {
21BCP430D Pranjal M. Patel

System.out.println("Drawing MEDIUM content in color : " +


color);
}
}

 PenFactory.java
package Fp2;

import java.util.HashMap;

public class PenFactory


{
private static final HashMap<String, Pen> pensMap = new
HashMap<>();

public static Pen getThickPen(String color)


{
String key = color + "-THICK";

Pen pen = pensMap.get(key);

if(pen != null) {
return pen;
} else {
pen = new ThickPen();
pen.setColor(color);
pensMap.put(key, pen);
}

return pen;
}

public static Pen getThinPen(String color)


{
String key = color + "-THIN";

Pen pen = pensMap.get(key);


21BCP430D Pranjal M. Patel

if(pen != null) {
return pen;
} else {
pen = new ThinPen();
pen.setColor(color);
pensMap.put(key, pen);
}

return pen;
}

public static Pen getMediumPen(String color)


{
String key = color + "-MEDIUM";

Pen pen = pensMap.get(key);

if(pen != null) {
return pen;
} else {
pen = new MediumPen();
pen.setColor(color);
pensMap.put(key, pen);
}

return pen;
}
}

 PaintBrushClient.java
package Fp2;

public class PaintBrushClient


{
public static void main(String[] args)
{
21BCP430D Pranjal M. Patel

Pen yellowThinPen1 = PenFactory.getThickPen("YELLOW");


//created new pen
yellowThinPen1.draw("Hello World !!");

Pen yellowThinPen2 = PenFactory.getThickPen("YELLOW");


//pen is shared
yellowThinPen2.draw("Hello World !!");

Pen blueThinPen = PenFactory.getThickPen("BLUE");


//created new pen
blueThinPen.draw("Hello World !!");

//System.out.println(yellowThinPen1.hashCode());
//System.out.println(yellowThinPen2.hashCode());

//System.out.println(blueThinPen.hashCode());
}
}

 Output:

You might also like