Monday, March 17, 2025

Abstract Factory Pattern in C#

Below is a C# implementation of the Abstract Factory design pattern, a Creational pattern, following the Gang of Four (GoF) structure. Each class is placed in its own file and created in an order that avoids dependency issues.


Class Creation Order

To avoid dependency issues, create the classes in this order:

  1. AbstractProductA & AbstractProductB (Abstract Products)
  2. ConcreteProductA1, ConcreteProductA2, ConcreteProductB1, ConcreteProductB2 (Concrete Products)
  3. AbstractFactory (Factory Interface)
  4. ConcreteFactory1 & ConcreteFactory2 (Factory Implementations)
  5. Client Code (Program.cs)

1. Abstract Products (IAbstractProductA.cs & IAbstractProductB.cs)

IAbstractProductA.cs

namespace AbstractFactoryPattern
{
    // Abstract Product A
    public interface IAbstractProductA
    {
        void Use();
    }
}

IAbstractProductB.cs

namespace AbstractFactoryPattern
{
    // Abstract Product B
    public interface IAbstractProductB
    {
        void Use();
    }
}

Explanation

IAbstractProductA and IAbstractProductB define the interfaces for two types of products.
Each product type has a Use() method, which will be implemented by concrete products.


2. Concrete Products

ConcreteProductA1.cs

using System;

namespace AbstractFactoryPattern
{
    // Concrete Product A1
    public class ConcreteProductA1 : IAbstractProductA
    {
        public void Use()
        {
            Console.WriteLine("Using ConcreteProductA1");
        }
    }
}

ConcreteProductA2.cs

using System;

namespace AbstractFactoryPattern
{
    // Concrete Product A2
    public class ConcreteProductA2 : IAbstractProductA
    {
        public void Use()
        {
            Console.WriteLine("Using ConcreteProductA2");
        }
    }
}

ConcreteProductB1.cs

using System;

namespace AbstractFactoryPattern
{
    // Concrete Product B1
    public class ConcreteProductB1 : IAbstractProductB
    {
        public void Use()
        {
            Console.WriteLine("Using ConcreteProductB1");
        }
    }
}

ConcreteProductB2.cs

using System;

namespace AbstractFactoryPattern
{
    // Concrete Product B2
    public class ConcreteProductB2 : IAbstractProductB
    {
        public void Use()
        {
            Console.WriteLine("Using ConcreteProductB2");
        }
    }
}

Explanation

ConcreteProductA1, ConcreteProductA2 implement IAbstractProductA.
ConcreteProductB1, ConcreteProductB2 implement IAbstractProductB.
These represent different product variations.


3. Abstract Factory (IAbstractFactory.cs)

namespace AbstractFactoryPattern
{
    // Abstract Factory Interface
    public interface IAbstractFactory
    {
        IAbstractProductA CreateProductA();
        IAbstractProductB CreateProductB();
    }
}

Explanation:
Defines CreateProductA() and CreateProductB(), which will be implemented by concrete factories.


4. Concrete Factories

ConcreteFactory1.cs

namespace AbstractFactoryPattern
{
    // Concrete Factory 1
    public class ConcreteFactory1 : IAbstractFactory
    {
        public IAbstractProductA CreateProductA()
        {
            return new ConcreteProductA1();
        }

        public IAbstractProductB CreateProductB()
        {
            return new ConcreteProductB1();
        }
    }
}

ConcreteFactory2.cs

namespace AbstractFactoryPattern
{
    // Concrete Factory 2
    public class ConcreteFactory2 : IAbstractFactory
    {
        public IAbstractProductA CreateProductA()
        {
            return new ConcreteProductA2();
        }

        public IAbstractProductB CreateProductB()
        {
            return new ConcreteProductB2();
        }
    }
}

Explanation:
ConcreteFactory1 creates ConcreteProductA1 and ConcreteProductB1.
ConcreteFactory2 creates ConcreteProductA2 and ConcreteProductB2.


5. Client Code (Program.cs)

using System;

namespace AbstractFactoryPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a factory of type 1
            IAbstractFactory factory1 = new ConcreteFactory1();
            IAbstractProductA productA1 = factory1.CreateProductA();
            IAbstractProductB productB1 = factory1.CreateProductB();

            productA1.Use(); // Output: Using ConcreteProductA1
            productB1.Use(); // Output: Using ConcreteProductB1

            // Create a factory of type 2
            IAbstractFactory factory2 = new ConcreteFactory2();
            IAbstractProductA productA2 = factory2.CreateProductA();
            IAbstractProductB productB2 = factory2.CreateProductB();

            productA2.Use(); // Output: Using ConcreteProductA2
            productB2.Use(); // Output: Using ConcreteProductB2
        }
    }
}

Final Explanation

  1. Abstract Products (IAbstractProductA, IAbstractProductB): Define interfaces for different types of products.
  2. Concrete Products: Implement the abstract product interfaces.
  3. Abstract Factory: Declares factory methods for creating products.
  4. Concrete Factories: Implement factory methods to produce different products.
  5. Client Code: Uses the abstract factory to create product families.

Key Takeaways

  • Encapsulation: The client is independent of concrete product classes.
  • Scalability: Easily add new product families without modifying existing code.
  • Consistency: Ensures related products are created together.
Would you like a downloadable version of this file or to have it combined with the C++/PHP HTML examples into a single learning package?

Tuesday, March 11, 2025

Below is a C++ implementation of the Abstract Factory design pattern, which is a Creational pattern, following the Gang of Four (GoF) structure. Each class is placed in its own file and created in an order that avoids dependency issues.


Class Creation Order

To avoid dependency errors, create the classes in this order:

  1. AbstractProductA & AbstractProductB (Abstract Products)
  2. ConcreteProductA1, ConcreteProductA2, ConcreteProductB1, ConcreteProductB2 (Concrete Products)
  3. AbstractFactory (Factory Interface)
  4. ConcreteFactory1 & ConcreteFactory2 (Factory Implementations)
  5. Client Code (main.cpp)

1. AbstractProductA.h & AbstractProductB.h (Abstract Products)

AbstractProductA.h

#ifndef ABSTRACTPRODUCTA_H
#define ABSTRACTPRODUCTA_H

// Abstract Product A
class AbstractProductA {
public:
    virtual void use() = 0; // Pure virtual function
    virtual ~AbstractProductA() {} // Virtual destructor
};

#endif // ABSTRACTPRODUCTA_H

AbstractProductB.h

#ifndef ABSTRACTPRODUCTB_H
#define ABSTRACTPRODUCTB_H

// Abstract Product B
class AbstractProductB {
public:
    virtual void use() = 0;
    virtual ~AbstractProductB() {} // Virtual destructor
};

#endif // ABSTRACTPRODUCTB_H

Explanation

AbstractProductA and AbstractProductB define the interfaces for the two types of products. Each abstract product contains a use() method, which will be implemented by concrete products.


2. Concrete Products

ConcreteProductA1.h

#ifndef CONCRETEPRODUCTA1_H
#define CONCRETEPRODUCTA1_H

#include "AbstractProductA.h"
#include <iostream>

// Concrete Product A1
class ConcreteProductA1 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using ConcreteProductA1" << std::endl;
    }
};

#endif // CONCRETEPRODUCTA1_H

ConcreteProductA2.h

#ifndef CONCRETEPRODUCTA2_H
#define CONCRETEPRODUCTA2_H

#include "AbstractProductA.h"
#include <iostream>

// Concrete Product A2
class ConcreteProductA2 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using ConcreteProductA2" << std::endl;
    }
};

#endif // CONCRETEPRODUCTA2_H

ConcreteProductB1.h

#ifndef CONCRETEPRODUCTB1_H
#define CONCRETEPRODUCTB1_H

#include "AbstractProductB.h"
#include <iostream>

// Concrete Product B1
class ConcreteProductB1 : public AbstractProductB {
public:
    void use() override {
        std::cout << "Using ConcreteProductB1" << std::endl;
    }
};

#endif // CONCRETEPRODUCTB1_H

ConcreteProductB2.h

#ifndef CONCRETEPRODUCTB2_H
#define CONCRETEPRODUCTB2_H

#include "AbstractProductB.h"
#include <iostream>

// Concrete Product B2
class ConcreteProductB2 : public AbstractProductB {
public:
    void use() override {
        std::cout << "Using ConcreteProductB2" << std::endl;
    }
};

#endif // CONCRETEPRODUCTB2_H

Explanation

ConcreteProductA1, ConcreteProductA2 implement AbstractProductA.
ConcreteProductB1, ConcreteProductB2 implement AbstractProductB.
These represent different product variations.


3. AbstractFactory.h (Abstract Factory Interface)

#ifndef ABSTRACTFACTORY_H
#define ABSTRACTFACTORY_H

#include "AbstractProductA.h"
#include "AbstractProductB.h"

// Abstract Factory Interface
class AbstractFactory {
public:
    virtual AbstractProductA* createProductA() = 0;
    virtual AbstractProductB* createProductB() = 0;
    virtual ~AbstractFactory() {} // Virtual destructor
};

#endif // ABSTRACTFACTORY_H

Explanation:
Defines createProductA() and createProductB(), which will be implemented by concrete factories.


4. Concrete Factories

ConcreteFactory1.h

#ifndef CONCRETEFACTORY1_H
#define CONCRETEFACTORY1_H

#include "AbstractFactory.h"
#include "ConcreteProductA1.h"
#include "ConcreteProductB1.h"

// Concrete Factory 1
class ConcreteFactory1 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ConcreteProductA1();
    }

    AbstractProductB* createProductB() override {
        return new ConcreteProductB1();
    }
};

#endif // CONCRETEFACTORY1_H

ConcreteFactory2.h

#ifndef CONCRETEFACTORY2_H
#define CONCRETEFACTORY2_H

#include "AbstractFactory.h"
#include "ConcreteProductA2.h"
#include "ConcreteProductB2.h"

// Concrete Factory 2
class ConcreteFactory2 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ConcreteProductA2();
    }

    AbstractProductB* createProductB() override {
        return new ConcreteProductB2();
    }
};

#endif // CONCRETEFACTORY2_H

Explanation:
ConcreteFactory1 creates ConcreteProductA1 and ConcreteProductB1.
ConcreteFactory2 creates ConcreteProductA2 and ConcreteProductB2.


5. main.cpp (Client Code)

#include <iostream>
#include "ConcreteFactory1.h"
#include "ConcreteFactory2.h"

int main() {
    // Create a factory of type 1
    AbstractFactory* factory1 = new ConcreteFactory1();
    AbstractProductA* productA1 = factory1->createProductA();
    AbstractProductB* productB1 = factory1->createProductB();

    productA1->use(); // Output: Using ConcreteProductA1
    productB1->use(); // Output: Using ConcreteProductB1

    // Create a factory of type 2
    AbstractFactory* factory2 = new ConcreteFactory2();
    AbstractProductA* productA2 = factory2->createProductA();
    AbstractProductB* productB2 = factory2->createProductB();

    productA2->use(); // Output: Using ConcreteProductA2
    productB2->use(); // Output: Using ConcreteProductB2

    // Cleanup
    delete productA1;
    delete productB1;
    delete factory1;

    delete productA2;
    delete productB2;
    delete factory2;

    return 0;
}

Final Explanation

  1. Abstract Products (AbstractProductA & AbstractProductB): Define interfaces for different types of products.
  2. Concrete Products: Implement the abstract products.
  3. Abstract Factory: Declares factory methods for creating products.
  4. Concrete Factories: Implement factory methods to produce different products.
  5. Client Code: Uses the abstract factory to create product families.

Key Takeaways

  • Encapsulation: The client is independent of concrete product classes.
  • Scalability: Easily add new product families without modifying existing code.
  • Consistency: Ensures related products are created together.

Monday, March 03, 2025

Factory Design Pattern in PHP

Here's the detailed breakdown and implementation of the Factory Design Pattern in PHP following the Gang of Four's approach.


Order of Class Creation

  1. Product Interface (Product.php) – Defines the interface that all concrete products must implement.
  2. Concrete Products (ConcreteProductA.php and ConcreteProductB.php) – Implement the product interface.
  3. Creator (Factory) Interface (Creator.php) – Declares the factory method.
  4. Concrete Factories (ConcreteCreatorA.php and ConcreteCreatorB.php) – Implement the factory method to create specific product instances.
  5. Client Code (index.php) – Uses the factory to create objects.

Factory Design Pattern in PHP

I'll generate the code in individual files, following the correct sequence.

1. Product Interface (Product.php)

<?php
// Product.php
// The Product interface declares the operations that all concrete products must implement.

interface Product {
    public function operation(): string;
}
?>
  

Explanation:
This interface ensures that all products created by the factory implement a common method operation().


2. Concrete Products (ConcreteProductA.php and ConcreteProductB.php)

Concrete Product A (ConcreteProductA.php)

<?php
// ConcreteProductA.php
// Implements the Product interface.

require_once "Product.php";

class ConcreteProductA implements Product {
    public function operation(): string {
        return "Result from ConcreteProductA";
    }
}
?>
  

Concrete Product B (ConcreteProductB.php)

<?php
// ConcreteProductB.php
// Implements the Product interface.

require_once "Product.php";

class ConcreteProductB implements Product {
    public function operation(): string {
        return "Result from ConcreteProductB";
    }
}
?>
  

Explanation:
Both ConcreteProductA and ConcreteProductB implement the Product interface.
Each class defines the operation() method, returning a string to identify itself.


3. Factory Interface (Creator.php)

<?php
// Creator.php
// The Creator class declares the factory method.

interface Creator {
    public function factoryMethod(): Product;
}
?>
  

Explanation:
This interface defines a method factoryMethod() that must be implemented by all concrete factories to produce a Product.


4. Concrete Factories (ConcreteCreatorA.php and ConcreteCreatorB.php)

Concrete Factory A (ConcreteCreatorA.php)

<?php
// ConcreteCreatorA.php
// Implements the Creator interface and produces ConcreteProductA.

require_once "Creator.php";
require_once "ConcreteProductA.php";

class ConcreteCreatorA implements Creator {
    public function factoryMethod(): Product {
        return new ConcreteProductA();
    }
}
?>
  

Concrete Factory B (ConcreteCreatorB.php)

<?php
// ConcreteCreatorB.php
// Implements the Creator interface and produces ConcreteProductB.

require_once "Creator.php";
require_once "ConcreteProductB.php";

class ConcreteCreatorB implements Creator {
    public function factoryMethod(): Product {
        return new ConcreteProductB();
    }
}
?>
  

Explanation:
ConcreteCreatorA and ConcreteCreatorB each implement Creator.
They override factoryMethod() to return an instance of a specific Product (ConcreteProductA or ConcreteProductB).


5. Client Code (index.php)

<?php
// index.php
// The client code calls the factory method to create objects.

require_once "ConcreteCreatorA.php";
require_once "ConcreteCreatorB.php";

/**
 * Function to test the factory pattern
 */
function clientCode(Creator $creator) {
    echo "Client: I'm working with " . get_class($creator) . "<br>";
    $product = $creator->factoryMethod();
    echo "Product says: " . $product->operation() . "<br><br>";
}

// Testing both factories
echo "<h2>Factory Method Pattern in PHP</h2>";

echo "<h3>Using ConcreteCreatorA:</h3>";
clientCode(new ConcreteCreatorA());

echo "<h3>Using ConcreteCreatorB:</h3>";
clientCode(new ConcreteCreatorB());

?>
  

Explanation:
The clientCode() function expects an object that implements Creator.
It calls the factoryMethod() to create a product and prints the result.
The index.php script tests both ConcreteCreatorA and ConcreteCreatorB, demonstrating the Factory Pattern in action.


Final Thoughts

This structured approach ensures:

  • Clear separation of concerns (each class has a single responsibility).
  • Encapsulation of object creation in the factory classes.
  • Scalability (new products can be introduced without altering existing code).

Abstract Factory Pattern in C#

Below is a C# implementation of the Abstract Factory design pattern, a Creational pattern, following the Gang of Four (GoF) structure....