Project – BookStore – Structural Patterns-2

The BookComposite class implements the following shared features:

  • Children management (highlighted in the code).
  • Setting the Name property of the composite object and forcing the classes inheriting it to set a name upon construction.
  • Automatically finds and sets the Type name of its derived class.
  • Counting the number of children (and, implicitly, the children’s children).
  • Exposing the children through the Children property and ensuring consumers can’t modify the collection from the outside by returning a ReadOnlyCollection object.

Using the LINQ Sum() extension method in the children.Sum(child => child.Count()); expression allowed us to replace a more complex for loop and an accumulator variable.

Adding the virtual modifier to the Type property allows sub-types to override the property in case their type’s name does not reflect the type that should be displayed in the program.

Now, we can start implementing the other classes of our complex composite hierarchy and assign a responsibility to each class, showing how flexible the Composite pattern is.The following classes inherit from the BookComposite class:

  • The Corporation class represents the corporation that owns multiple stores. However, it is not limited to owning stores; a corporation could own other corporations, stores, or any other IComponent.
  • The Store class represents a bookstore.
  • The Section class represents a section of a bookstore, an aisle, or a category of books.
  • The Set class represents a book set, such as a trilogy.

These can be composed of any IComponent, making this an ultra-flexible data structure. Let’s look at the code for these BookComposite sub-types, starting with the Corporation class:

namespace Composite.Models;
public class Corporation : BookComposite
{
    public Corporation(string name, string ceo)
        : base(name)
    {
        CEO = ceo;
    }
    public string CEO { get; }
}

The corporation contributes a CEO to the model because someone has to manage the place.Next, we look at the Store class:

namespace Composite.Models;
public class Store : BookComposite
{
    public string Location { get; }
    public string Manager { get; }
    public Store(string name, string location, string manager)
        : base(name)
    {
        Location = location;
        Manager = manager;
    }
}

On top of the BookComposite members, a store has a manager and a location.Now, the Section class does not add anything, but we can use it as a flexible organizer:namespace Composite.Models;

public class Section : BookComposite
{
    public Section(string name) : base(name) { }
}

Finally, the Set class allows creating the book set upon construction through the books parameter:

namespace Composite.Models;
public class Set : BookComposite
{
    public Set(string name, params IComponent[] books)
        : base(name)
    {
        foreach (var book in books)
        {
            Add(book);
        }
    }
}

Composing a set of books upon creation of the instance will be convenient later when we assemble the tree.Next, let’s explore the last part of the program that helps encapsulate the data structure’s creation: the factory.

The factory is not part of the Composite pattern, but now that we know what a factory is, we can use one to encapsulate the creation logic of our data structure and talk about it.

The factory interface looks like the following:

public interface ICorporationFactory
{
    Corporation Create();
}

The default concrete implementation of the ICorporationFactory interface is the DefaultCorporationFactory class. It creates a large non-linear data structure with sections, subsections, sets, and subsets. This whole structure is defined using our composite model in the DefaultCorporationFactory class. Due to its large size, let’s start with the class’s skeleton and its Create method:

using Composite.Models;
namespace Composite.Services;
public class DefaultCorporationFactory : ICorporationFactory
{
    public Corporation Create()
    {
        var corporation = new Corporation(
            “Boundless Shelves Corporation”,
            “Bosmang Kapawu”
        );
        corporation.Add(CreateTaleTowersStore());
        corporation.Add(CreateEpicNexusStore());
        return corporation;
    }
    // …
}

Leave a Reply

Your email address will not be published. Required fields are marked *



          Copyright © 2015-2024 | About | Terms of Service | Privacy Policy