Coder Social home page Coder Social logo

bengreenier / cppfactory Goto Github PK

View Code? Open in Web Editor NEW
12.0 3.0 3.0 164 KB

Modern c++ object factory implementation in <200 lines

Home Page: https://bengreenier.github.io/CppFactory

License: MIT License

C++ 100.00%
cpp design-patterns factory-pattern cpp-11

cppfactory's Introduction

CppFactory

Modern c++ object factory implementation in <200 lines ๐Ÿ“ฆ ๐Ÿญ

build status

I needed a simple to use, easy to mock c++ factory library (that could be used for dependecy injection) and a quick search didn't yield what I was looking for. So I built this one. Read the API docs - (raw) - (hosted).

Concepts

Some terminology you may not be familiar with, but you'll want to know.

Object Lifecycle

In CppFactory, objects are all captured in std::shared_ptr wrappers, so there is no need to worry about manually deleting objects that you retrieve via the Object<TObject>::Get() call. However, you may choose to modify how the runtime handles object allocation to optimize for your use case.

By default, Objects are unmanaged, meaning when the object returned (by Object<TObject>::Get()) falls out of scope it is destroyed. This works great for object types that are not re-used (or if you wish to manage lifetime yourself). However, for something with a longer life (perhaps a representation of a database connection) that will be reused in many places, you may use a GlobalObject. GlobalObjects are powered by Objects under the hood, meaning that you can still configure allocators at the Object level. All GlobalObject provides is a lightweight caching wrapper around the Object<TObject>::Get() method. This looks like the following:

GlobalObject<TObject>::Get()

To clear the GlobalObject cache, simply call GlobalObject<TObject>::Reset() or (to reset only a single zone, for example 10) GlobalObject<TObject>::Reset<10>().

Object Zones

In CppFactory, objects of the same type are all retrieved from the same factory, so it can become difficult to work with different instances of the same type. To deal with this, CppFactory provides a concept of zones.

Zones enable you to draw logical boundries throughout your codebase and to retrieve instances only for that zone. To represent this, you may pass an int to Get(), RegisterAllocator() and RemoveGlobal() as a template parameter. The int is how CppFactory represents a zone, and tracks object allocation within that zone. Here's an example:

Object<TObject>::Get<10>()

You may also use an enum (backed by an int) to represent zones, which looks like the following:

enum Zones
{
    ZoneOne,
    ZoneTwo
}

Object<TObject>::Get<Zones::ZoneOne>()

Note that you'll likely find this most useful when coupled with GlobalObject.

Usage

Using constructors and destructors:

#include <CppFactory/CppFactory.hpp>

using namespace CppFactory;

struct Data
{
    int Value;
};

int main()
{
    // using default allocator (ctor)
    std::shared_ptr<Data> object = Object<Data>::Get();
    object->Value = 2;

    // a global object using the default allocator (ctor)
    std::shared_ptr<Data> global = GlobalObject<Data>::Get();

    return 0;
}

Using custom allocators and deallocators:

#include <CppFactory/CppFactory.hpp>

using namespace CppFactory;

struct Data
{
    int Value;
};

int main()
{
    Object<Data>::RegisterAllocator([] {
        // custom allocator
        auto ptr = (Data*)malloc(sizeof(Data));
        ptr->Value = 0;

        // custom deallocator
        return std::shared_ptr<Data>(ptr, [](Data* data) { free(data); });
    });

    // use defined allocator
    std::shared_ptr<Data> object = Object<Data>::Get();
    object->Value = 2;

    // a global object using the allocator
    std::shared_ptr<Data> global = GlobalObject<Data>::Get();

    return 0;
}

Using factory object pattern (old school):

#include <CppFactory/CppFactory.hpp>

using namespace CppFactory;

struct Data
{
    int Value;
};

int main()
{
    Factory<Data> factory;

    // use defined allocator
    std::shared_ptr<Data> object = factory.Allocate();
    object->Value = 2;

    return 0;
}

Using factory object pattern (custom factory):

#include <CppFactory/CppFactory.hpp>

using namespace CppFactory;

struct DataArgs
{
    int Value;
    int Value2;

    DataArgs(int value, int value2) : Value(value), Value2(value2) {}
};

int main()
{
    Factory<DataArgs, int, int> factory;

    // use defined allocator
    std::shared_ptr<Data> object = factory.Allocate(10, 20);
    // object->Value == 10;
    // object->Value2 == 20;

    return 0;
}

See the tests for more examples.

Timing

Note: Test runs 10000 iterations for each type below. See the code here.

Untracked, normal alloc: 34ms (0.003400ms / iteration)
Global, normal alloc: 36ms (0.003600ms / iteration)
Untracked, slow alloc: 110694ms (11.069400ms / iteration)
Global, slow alloc: 62ms (0.006200ms / iteration)

License

MIT

cppfactory's People

Contributors

bengreenier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

cppfactory's Issues

Factory should use unique_ptr

Today, the Factory class returns shared_ptr on Allocate(...) calls - it should instead return unique_ptr as we do not continue to own the lifetime of the pointer, nor do we maintain a reference to it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.