0% found this document useful (0 votes)
18 views15 pages

Lab#07 Abstract Factory Design Pattern

The document discusses the Abstract Factory Pattern, a creational design pattern that allows for the creation of families of related objects without specifying their concrete classes. It emphasizes decoupling client code from concrete implementations, promoting flexibility, maintainability, and extensibility in software design. The document also provides real-life analogies and examples, particularly in the context of user interface components and a restaurant analogy, to illustrate the pattern's application and benefits.

Uploaded by

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

Lab#07 Abstract Factory Design Pattern

The document discusses the Abstract Factory Pattern, a creational design pattern that allows for the creation of families of related objects without specifying their concrete classes. It emphasizes decoupling client code from concrete implementations, promoting flexibility, maintainability, and extensibility in software design. The document also provides real-life analogies and examples, particularly in the context of user interface components and a restaurant analogy, to illustrate the pattern's application and benefits.

Uploaded by

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

Department of Software Engineering

Mehran University of Engineering and Technology, Jamshoro

SW227 – SOFTWARE DESIGN AND ARCHITECTURE


Instructor Ms. Afifah Jalbani Practical/Lab No. 07
Date 10-03-2025 CLOs 3
Signature Assessment Score 1 Mark

Topic
Objectives - To implement Abstract Factory Pattern

Lab Discussion: Theoretical concepts and Procedural steps

Theory:
Abstract Factory Pattern
The Abstract Factory is a design pattern that falls under the Creational design patterns
category. Its main purpose is to create families of related or dependent objects without specifying
their exact concrete classes. This pattern encapsulates a group of individual factories that have a
common theme, enabling the client to work with them via a simplified interface. The client remains
decoupled from the details of how these objects are created, and they are only aware of the abstract
types, not the concrete ones.
It promotes flexibility in the code by creating objects without specifying their exact classes.
Instead, the pattern relies on interfaces or abstract classes to define the types of objects to be
created. This allows the client code to remain independent of the concrete implementations.
Here's a breakdown of how this flexibility is achieved:

1. Decoupling of Client Code from Concrete Classes

The client interacts only with abstract types (interfaces or abstract classes), such as Button or
Checkbox. It doesn't need to know whether it’s creating a WindowsButton, MacOSButton, or any
other concrete type. This way, the client code doesn’t need to change if new product families are
introduced (e.g., adding Linux buttons).

2. Runtime Selection of Object Creation

The actual class of the object to be created is determined at runtime. For instance, the client could be
using the MacOSFactory today, and tomorrow it might use the WindowsFactory. This dynamic
decision-making provides tremendous flexibility, as different object families can be swapped in or
out based on configuration, user choice, or system environment.

3. Easier Maintenance and Extensibility

Because the concrete classes are hidden behind interfaces or abstract classes, you can add new
product families (e.g., adding a LinuxFactory) without changing the client code. You only need to

1
provide a new factory and its corresponding product classes. This promotes maintainability and
scalability of the code.

Factories and Products

 Factories: In the Abstract Factory pattern, a factory is an object that is responsible for creating
families of related objects (products). The factory abstracts the creation of objects, so the client
code does not directly instantiate the products. Instead, the client interacts with the factory
interface, which creates the objects for it.

Example: Imagine you are building a user interface for different operating systems like Windows
or MacOS. A WindowsFactory would create Windows-specific UI components (buttons,
checkboxes), and a MacOSFactory would create MacOS-specific UI components.

 Products: Products are the objects (classes) created by the factories. In the Abstract Factory
pattern, the products are part of a family of related objects (like buttons and checkboxes for a
particular OS). Each factory is responsible for creating a specific type of product family (e.g.,
Windows components or MacOS components).

Example: In the case of UI components, a Button and a Checkbox are products. The
WindowsFactory creates a WindowsButton and WindowsCheckbox, while the MacOSFactory
creates a MacOSButton and MacOSCheckbox.

◦ Intent: Provide an interface for creating families of related or dependent objects without
specifying their concrete classes.
◦ Also Known As: Kit

Abstract Factory Pattern in Real Life

This real-life example uses a restaurant analogy to explain the Abstract Factory design pattern.
Let’s break it down in detail:

1. Restaurant as the System

In this analogy, the restaurant represents the overall system where the Abstract Factory pattern is
being applied. Just like in the pattern, the restaurant doesn’t directly prepare food, but instead relies
on different experts (chefs) to handle specific types of cuisines.

2
2. Orders as Client Requests

When a customer places an order, it represents the client's request in a software system. The client
doesn't care who exactly is preparing the food, only that the requested dish is delivered.

In the software world, the client makes a request to create a family of objects (like buttons and
checkboxes in our earlier example), but doesn't care about the concrete implementation.

3. Kitchen as the Abstract Factory

The kitchen is like the Abstract Factory in the design pattern. It doesn't cook the food itself;
instead, it delegates the work to the appropriate chefs. Similarly, the Abstract Factory doesn’t directly
create objects but provides an interface that delegates the object creation to the concrete factories
(which, in this case, are the chefs).

In the restaurant:

 The kitchen assigns orders to the respective chefs (factories).


 The chefs are the ones who prepare the food (concrete products) based on the specific cuisine
requested (Chinese, Indian, Continental).

4. Chefs as Concrete Factories

The chefs represent the concrete factories in the Abstract Factory pattern. Each chef is specialized in
a particular cuisine (e.g., Chinese, Indian, Continental), and each chef knows how to prepare all the
dishes (products) related to their cuisine.

 Chinese Chef: Prepares Chinese dishes like noodles or dumplings.


 Indian Chef: Prepares Indian dishes like curry or naan.
 Continental Chef: Prepares continental dishes like steak or pasta.

In software terms, each chef (concrete factory) is responsible for creating a set of related objects. For
example, if you have a GUIFactory interface, one factory might create Windows-style UI
components, while another creates MacOS-style components. Here, the chef is the equivalent of a
factory, and the dishes are the products.

5. Dishes as Products

The dishes are the products created by the concrete factories (chefs). Each chef produces a specific
type of product based on their expertise:

 Chinese Chef makes Chinese dishes.


 Indian Chef makes Indian dishes.
 Continental Chef makes Continental dishes.

In the Abstract Factory pattern, the products are related. For instance, in a GUI application, a
"family" of products might be related components like buttons and checkboxes, all styled in a similar
way (e.g., Windows style, MacOS style). Similarly, in the restaurant, all dishes made by the Chinese
chef belong to the Chinese cuisine family.

3
6. Client Code (Restaurant Manager or Waiter)

In this example, the waiter or restaurant manager interacts with the kitchen (Abstract Factory) and
gives it orders from the clients (customers). The waiter is unaware of which specific chef will make
the dish, just as the client code in the Abstract Factory pattern is unaware of which concrete class will
be used to create the product. The waiter only knows that the kitchen will take care of delegating the
task to the right chef.

Conclusion:

The Abstract Factory Pattern in this restaurant example works as follows:

 Client (Customer) makes a request (order).


 The Abstract Factory (Kitchen) doesn’t directly handle the request but delegates it to
Concrete Factories (Chefs), which are specialized in creating specific families of products
(dishes).
 Each Concrete Factory (Chef) produces a specific type of product (Chinese, Indian, or
Continental dish), ensuring that all products related to a particular family are created by the
same factory.
 The Client (Customer) gets the final product (food), without knowing or needing to know


 who specifically prepared it (decoupling).

This analogy simplifies the idea that the Abstract Factory Pattern allows for the creation of related
products (dishes) without the client knowing the details of the concrete implementations.

Abstract Factory Pattern in Java: Structure

4
This class diagram illustrates the Abstract Factory Pattern in Java, which is used to create families
of related or dependent objects without specifying their concrete classes. Let’s break down each
component in detail.

1. AbstractFactory Interface (Top Left)

 The AbstractFactory interface declares the factory methods for creating abstract products.
 It contains two methods:
o createProductA(): Creates and returns an instance of AbstractProductA.
o createProductB(): Creates and returns an instance of AbstractProductB.

This factory defines an interface that concrete factories will implement.

2. Concrete Factories (Middle Left)

 ConcreteFactory1 and ConcreteFactory2 are implementations of the AbstractFactory


interface.
 Each factory is responsible for producing products from a specific family.
o ConcreteFactory1 creates ProductA1 and ProductB1.
o ConcreteFactory2 creates ProductA2 and ProductB2 (highlighted in red in the
diagram).

These concrete factories implement the abstract methods createProductA() and


createProductB() to return instances of their respective concrete products.

3. Abstract Products (Top Right)

5
 The AbstractProductA and AbstractProductB represent interfaces or abstract classes for
products in the product family.
o AbstractProductA is an interface for products of type A.
o AbstractProductB is an interface for products of type B.

These define the structure or behavior that all products of their type should follow.

4. Concrete Products (Bottom Right)

 The Concrete Products are the actual instances that the concrete factories create. They
implement the respective abstract products:
o ProductA1 and ProductA2 implement AbstractProductA.
o ProductB1 and ProductB2 implement AbstractProductB.

Each concrete product belongs to a product family, which ensures that products created by a
factory are compatible with each other.

o ProductA1 and ProductB1 are created by ConcreteFactory1.


o ProductA2 and ProductB2 (in red) are created by ConcreteFactory2.

5. Client (Top Right)

 The client interacts only with the abstract factory and abstract products. It does not need to
know about the concrete classes.
 The client class is responsible for using the AbstractFactory interface to create the desired
products.
 The client works with AbstractProductA and AbstractProductB and is decoupled from the
actual implementation (concrete products like ProductA1, ProductB1, etc.).

How It Works:

1. The client code calls the AbstractFactory interface to create product objects.
2. A Concrete Factory (e.g., ConcreteFactory1 or ConcreteFactory2) is instantiated, and
the client uses this factory to get instances of products.
3. Based on the concrete factory, the appropriate product families are produced:
o ConcreteFactory1 produces ProductA1 and ProductB1.
o ConcreteFactory2 produces ProductA2 and ProductB2.

Key Points:

 The Abstract Factory Pattern ensures that the products created by a factory are compatible
with each other.
 The client interacts with the factory and product interfaces, remaining unaware of the actual
concrete implementations.
 You can easily extend this system by adding new product families (new concrete factories
and products) without modifying the existing client code or factory interface.

This design is useful when creating products that are related, or when families of products need to be
used together, like different styles of user interface components (Windows vs. Mac UI elements).

6
Motivation
Consider a garments factory specialized in creating trousers and shirts. Now the Parent
company which is a famous Retail brand is now venturing into Gadget section. They are also
planning to expand their Factories having one center in US and another one in UK. The client should
be completely unaware of how the objects are created. What is the best design pattern we can use to
resolve this requirement?

This class diagram depicts a variation of the Abstract Factory Design Pattern. In this pattern, the
goal is to create families of related objects (in this case, gadgets and garments) without specifying
their concrete classes. Let’s break down the elements of the diagram step by step:

1. Client

 The Client is the main part of the application that uses the abstract factory to obtain product
instances.
 It calls the factory methods without knowing the exact details of the object creation.
 The method main(String[] args) is the entry point, where it interacts with the
RetailFactory to create products.

2. RetailFactory Interface

 This interface declares two abstract methods:


o createGadgets(String): GadgetType
o createGarments(String): GarmentType

7
These methods are responsible for creating products in two categories: gadgets and garments.
The concrete factories (UKFactory, USFactory) will implement this interface to create their
specific products.

3. Concrete Factories (UKFactory and USFactory)

 UKFactory and USFactory are the concrete implementations of the RetailFactory


interface.
 They implement the methods:
o createGadgets(String): GadgetType
o createGarments(String): GarmentType

These factories provide specific products based on the region (UK or US). For example:

o UKFactory might create gadgets and garments that conform to UK standards or styles.
o USFactory might create gadgets and garments that conform to US standards or styles.

4. GadgetType Interface

 This interface represents the abstract product for gadgets. It declares the print() method,
which must be implemented by all gadgets.
 The print() method returns a String representation of the product details.

5. GarmentType Interface

 Similar to GadgetType, the GarmentType interface is the abstract product for garments. It
declares the print() method.
 The concrete garment products (e.g., Shirt, Trouser) will implement this interface.

6. Concrete Gadget Products (Laptop and Mobile)

 Laptop and Mobile are concrete implementations of the GadgetType interface.


o These classes implement the print() method to return details specific to the laptop or
mobile device.

These products are created by the createGadgets() method in the concrete factories.

7. Concrete Garment Products (Shirt and Trouser)

 Shirt and Trouser are concrete implementations of the GarmentType interface.


o These classes implement the print() method to return details specific to the shirt or
trousers.

These products are created by the createGarments() method in the concrete factories.

8. FactoryMaker

 The FactoryMaker is a utility class that contains logic to select the appropriate
RetailFactory based on a condition (such as the region).

8
o The private field abstractFactory: RetailFactory = null holds the currently
selected factory.
o The method getFactory(String): RetailFactory returns a concrete factory
(either UKFactory or USFactory) based on the input string.

This class helps in deciding which concrete factory (UK or US) should be used by the client.

How it Works:

1. Client Interaction:
o The client doesn't interact with the concrete classes (e.g., Laptop, Shirt) directly.
Instead, it uses the RetailFactory interface to create products.
2. Factory Selection:
o The FactoryMaker class decides which concrete factory (UKFactory or USFactory)
to use based on some condition (likely a region or configuration input).
3. Product Creation:
o Once the concrete factory is chosen (e.g., UKFactory), the createGadgets() and
createGarments() methods are called to create products like Laptop, Mobile,
Shirt, or Trouser.
o These products implement either the GadgetType or GarmentType interfaces and are
used by the client.

Key Concepts:

 Abstract Factory: The RetailFactory interface is the abstract factory that provides
methods to create related products (GadgetType and GarmentType).
 Concrete Factory: The UKFactory and USFactory implement the abstract factory to produce
products specific to their regions.
 Abstract Product: GadgetType and GarmentType are abstract products that define a
common interface (print()) for concrete products.
 Concrete Product: Laptop, Mobile, Shirt, and Trouser are the actual objects created by
the factories.

Benefits:

 Decoupling: The client code is decoupled from the concrete product classes. The client only
knows about the abstract factory and abstract products.
 Flexibility: New factories (like an EU factory) or new product categories (e.g., electronics,
footwear) can be added without changing the client code.

This structure is useful for applications where product families vary by context or environment (like
region-based gadgets and garments), allowing easy scalability and maintainability.

Applicability
Use the Abstract Factory pattern when a system should be independent of how its products
are created, composed, and represented. A system should be configured with one of multiple families
of products. A family of related product objects is designed to be used together, and you need to

9
enforce this constraint. You want to provide a class library of products, and you want to reveal just
their interfaces, not their implementations.

Participants
1. AbstractFactory:
Declares an interface for operations that create abstract product objects.
2. ConcreteFactory:
Implements the operations to create concrete product objects.
3. AbstractProduct:
Declares an interface for a type of product object.
4. ConcreteProduct:
Defines a product object to be created by the corresponding concrete factory. Implements the
AbstractProduct interface.
5. Client:
Uses only interfaces declared by AbstractFactory and AbstractProduct classes.

Practical Example: GUI Themes

Let’s take an example of creating different types of GUI themes (e.g., MacOS GUI and Windows
GUI). Each theme will have related products, such as buttons and checkboxes. The client needs to
interact with the GUI factory without knowing whether it's creating MacOS or Windows
components.

Sample Code (Implementation)

1. Abstract Product Interface for Buttons:

Description: This file defines the abstract product interface for buttons. It contains the paint()
method, which will be implemented by all concrete button classes (e.g., MacOSButton,
WindowsButton). The interface ensures that all button classes will have a paint() method, even
though the specific implementation may vary.

2. Concrete Product for MacOS Button:

Description: This file contains the concrete product implementation for a MacOS-style button. It
implements the Button interface and provides the paint() method specific to MacOS buttons,
which will display a message indicating that a MacOS button is being rendered.

10
3. Concrete Product for Windows Button:

Description: This file contains the concrete product implementation for a Windows-style button.
It implements the Button interface and provides the paint() method specific to Windows buttons,
which will display a message indicating that a Windows button is being rendered.

4. Abstract Product Interface for Checkboxes:

Description: This file defines the abstract product interface for checkboxes. It contains the
check() method, which will be implemented by all concrete checkbox classes (e.g.,
MacOSCheckbox, WindowsCheckbox). The interface ensures that all checkbox classes will have
a check() method.

5. Concrete Product for MacOS Checkbox:

Description: This file contains the concrete product implementation for a MacOS-style
checkbox. It implements the Checkbox interface and provides the check() method specific to
MacOS checkboxes, which will display a message indicating that a MacOS checkbox is being
selected.

11
6. Concrete Product for Windows Checkbox:

Description: This file contains the concrete product implementation for a Windows-style
checkbox. It implements the Checkbox interface and provides the check() method specific to
Windows checkboxes, which will display a message indicating that a Windows checkbox is being
selected.

7. Abstract Factory Interface:

Description: This file defines the abstract factory interface. It declares two methods:
createButton() and createCheckbox(). These methods will be implemented by concrete
factories (like MacOSFactory and WindowsFactory) to create specific product instances (buttons
and checkboxes). The interface allows the client to create families of related products without
knowing the exact product types.

12
8. Concrete Factory for MacOS GUI:

Description: This file contains the concrete factory implementation for creating MacOS-style
GUI components. It implements the GUIFactory interface and provides concrete
implementations for the createButton() and createCheckbox() methods, returning MacOS-
specific button and checkbox objects.

9. Concrete Factory for Windows GUI:

Description: This file contains the concrete factory implementation for creating Windows-style
GUI components. It implements the GUIFactory interface and provides concrete
implementations for the createButton() and createCheckbox() methods, returning Windows-
specific button and checkbox objects.

13
10. Client Code:

Description: This file represents the client class. The Application class depends on the
GUIFactory interface to create and use buttons and checkboxes, but it doesn’t know the specific
details of the concrete factories or products. The Application class is responsible for calling the
factory methods and running the application by interacting with the abstract products (button and
checkbox).

11. Demo.java

Description: This file contains the main class to run the program. It simulates the client selecting
the operating system type (MacOS or Windows) and then creates the appropriate factory
(MacOSFactory or WindowsFactory). The Demo class passes the selected factory to the
Application class, which runs the GUI creation process. This is the file that should be run to see
the program's output.

14
Summary of Files:

 Abstract Products: Button.java, Checkbox.java


 Concrete Products: MacOSButton.java, WindowsButton.java, MacOSCheckbox.java,
WindowsCheckbox.java
 Abstract Factory: GUIFactory.java
 Concrete Factories: MacOSFactory.java, WindowsFactory.java
 Client Code: Application.java
 Main Class to Run: Demo.java

To run the code and display the output, compile all the Java files and execute the Demo.java class.

Related Patterns
◦ AbstractFactory classes are often implemented with factory methods (Factory Method), but
they can also be implemented using Prototype.
◦ A concrete factory is often a singleton (Singleton).

Lab Tasks:

1. Implement the Abstract Factory Pattern. Class diagram is given below:

2. Create a notification service through email, SMS, and push notification via the implementation of
Factory Pattern.

15

You might also like