jeudi 3 mai 2018

Implementation of a generic factory design pattern

I like using factory design pattern to inject dependencies, but that means having lots of very similar classes (almost one factory per class). Then I got to an idea to create a generic factory pattern using templates. Something like this:

// g++ -std=c++14 -Wall -Wextra factory.cpp -o factory


#include <functional>
#include <memory>
#include <utility>
#include <iostream>



template < typename T, typename Base = typename T::Iface >
class Factory
{
public:

    template < typename... Args >
    using CreatorFn = std::function< std::shared_ptr< Base > ( Args&&... ) >;

    template < typename... Args >
    static std::shared_ptr< Base > Create( Args&&... args );

    template < typename... Args >
    static void ResetToDefaultCreator();

    template < typename... Args >
    static void SetCreator( CreatorFn< Args... > fn );

private:
    Factory() = delete;

    template < typename... Args >
    static CreatorFn< Args... >& Creator();

    template < typename... Args >
    static std::shared_ptr< Base > DefaultCreator( Args&&... args );
};



template < typename T, typename Base >
template < typename... Args >
std::shared_ptr< Base > Factory< T, Base >::Create( Args&&... args )
{
    return Creator< Args... >()( std::forward< Args >( args )... );
}


template < typename T, typename Base >
template < typename... Args >
void Factory< T, Base >::ResetToDefaultCreator()
{
    CreatorFn< Args... >() = DefaultCreator< Args... >;
}

template < typename T, typename Base >
template < typename... Args >
void Factory< T, Base >::SetCreator( CreatorFn< Args... > fn )
{
    Creator< Args... >() = fn;
}

template < typename T, typename Base >
template < typename... Args >
Factory< T, Base >::CreatorFn< Args... >& Factory< T, Base >::Creator()
{
    static CreatorFn< Args... > creator = DefaultCreator< Args... >;
    return creator;
}

template < typename T, typename Base >
template < typename... Args >
std::shared_ptr< Base > Factory< T, Base >::DefaultCreator( Args&&... args )
{
    return std::make_shared< T >( std::forward< Args >( args )... );
}


struct A {
    virtual ~A() = default;

    virtual void foo() = 0;
};

struct B : public A {
    using Iface = A;

    virtual void foo()
    {
    }
};

struct C : public A {
    using Iface = A;

    C( int, float )
    {
    }

    virtual void foo()
    {
    }
};

struct D : public A {
    using Iface = A;

    D( int, float )
    {
    }

    virtual void foo()
    {
    }
};

using FactoryDefaultConstructor = Factory< B >;
using FactoryParamsConstructor  = Factory< C >;



int main()
{
    FactoryParamsConstructor::ResetToDefaultCreator<int,float>();

    std::shared_ptr< A > obj1 = FactoryParamsConstructor::Create( 3, 5 );
    C* realObj1 = dynamic_cast< C* >( obj1.get() );
    if ( nullptr != realObj1 )
    {
        std::cout << "1 created" << std::endl;
    }
    else
    {
        std::cout << "1 failed" << std::endl;
    }

    FactoryParamsConstructor::CreatorFn< int, float > newCretorFn = []( int a,float b ){
                                    std::cout << "****cb called"<<std::endl;
                                    return std::shared_ptr< A >( new D( a, b ) );
                            };
    FactoryParamsConstructor::SetCreator< int, float >( newCretorFn );
    std::shared_ptr< A > obj2 = FactoryParamsConstructor::Create( 3, 5.7f );
    D* realObj2 = dynamic_cast< D* >( obj2.get() );
    if ( nullptr != realObj2 )
    {
        std::cout << "2 created" << std::endl;
    }
    else
    {
        std::cout << "2 failed" << std::endl;
    }

    float p = 5.5f;
    std::shared_ptr< A > obj3 = FactoryParamsConstructor::Create( 3, p );
    D* realObj3 = dynamic_cast< D* >( obj3.get() );
    if ( nullptr != realObj3 )
    {
        std::cout << "3 created" << std::endl;
    }
    else
    {
        std::cout << "3 failed" << std::endl;
    }
}

Output:

1 created
****cb called
2 created
3 failed

This works, but with certain problems:

  1. if I don't take care what I pass to the Create() method, it can fail, since it is going to use wrong instance of the Creator() method. Is there a way to fix this? This is the reason why creation of obj3 fails.
  2. The SetCreator() method can take only std::function objects. I understand why. My question is, can I change it to take anything appropriate and call correct Creator() method? Ideally, it would have this declaration:

    template < typename F > static void SetCreator( F fn );

Then I could do this:

std::shared_ptr< A > foo( int, float ) { return new B; };
FactoryParamsConstructor::SetCreator( foo );

Jsoup matching tag with column

for a school project i need to parse arXiv.org API response code, to harvest some informations. I'm using Jsoup and i'm stuck on a problem:

I have a tag like this:

String value = document.select("arxiv:comment").text();

But this give me this error:

Exception in thread "main" org.jsoup.select.Selector$SelectorParseException: Could not parse query 'arxiv:comment': unexpected token at ':comment'

mercredi 2 mai 2018

Best pattern to use in a monitoring utility?

I'm trying to build a generic C# program of which the only purpose is to look at many classes that implement an IMonitoring interface, and execute the different steps each class implements.

The purpose of the monitoring is to check for the response time of different APIs, but trying to build it to be extensible to other type of services.

I'm trying to decide between having specific steps on the interface (like Initialize(), Execute(), LogResults()), or if the interface should have just one "Execute" method and then each implementing class can decide what steps it wants to follow.

The issue with implementing multiple steps on the interface is that I'd be limiting to those steps, even if I added some "hook" methods, but I don't think I can anticipate how many hooks and where to add them.

On the other side, if I have a single method, I fear that the implementing classes will not be very consistent.

Trying to keep this open-closed and extensible, but I'm not sure what the best solution would be.

How to eliminate switch-case in cod?

Lets say I have a switch case that looks something like this: (just an example)

switch(Type) {
    case MSSQL:   /
      Connector = new MSSQLCOnnector(
              args);
      break;
    case MYSQL:
      Connector = new MYSQLConnector(
              different_args);
      break;
    case ORACLE:
      databaseConnector = new OracleConnector(
              again_different_args);
      break;
      default:
          break;
  }

Since Switch-case violates OCP, is there a way to eliminate it, and use something else in code?

Thank you.

User statistics

Is user statistics capturing (e.g. which user entered which website and how many times) usually implemented using a log or a DB? Log requires parsing while DB is quite an overhead.

How do major companies (like Google or Amazon) implement it?

Finding a string pattern in a list

I have a string list with logs of process like this:

  • Processing rule 20247, inventory 2661866
  • Processing rule 20241, inventory 2662223
  • Enviando a app 0 inventories
  • Enviando a app 5 inventories
  • Aplicando reglas del 2018-05-07
  • Guardando log para el NDO actual (count=2)
  • Aplicando reglas del 2018-05-08
  • Guardando log para el NDO actual (count=1)
  • Processing rule 20247, inventory 2639899
  • Processing rule 20241, inventory 2640295

And I want to make some method to retrieve the differents patterns that we have in that list. For eg.:

  • Processing rule {0}, inventory {1}
  • Enviando a app {0} inventories
  • Aplicando reglas del {0}
  • Guardando log para el NDO actual (count={0})

The main idea is that I don't want to code every possible pattern, insted of this I'm thinking in using some Machine Learning so if tomorrow I have a new pattern in the list I don't have to code nothing else. I don't have problem if I need to train the system.

Someone know any example that I can follow to do this? Thank you!

How would PizzaStore accept different factories when depending on SimplePizzaFactory?

When I'm reading factory pattern of Head First Design Patterns, I'm confused when reading the simple factory part. Here is the class diagram. enter image description here

PizzaStore code:

 public class PizzaStore {

  SimplePizzaFactory factory;

  public PizzaStore(SimplePizzaFactory factory) {
    this.factory = factory;
  }

  public Pizza orderPizza(String type) {
    Pizza pizza;
    pizza = factory.createPizza(type);
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
  }
// other methods here
}

code for SimplePizzaFactory

public class SimplePizzaFactory {

  public Pizza createPizza(String type) {
    Pizza pizza = null;
    if (type.equals("cheese")) {
      pizza = new CheesePizza();
    } else if (type.equals("pepperoni")) {
      pizza = new PepperoniPizza();
    } else if (type.equals("clam")) {
      pizza = new ClamPizza();
    } else if (type.equals("veggie")) {
      pizza = new VeggiePizza();
    }
    return pizza; 
  }
}

in Franchising the pizza store part, it says:

If we take out SimplePizzaFactory and create three different factories, NYPizzaFactory, ChicagoPizzaFactory and CaliforniaPizzaFactory, then we can just compose the PizzaStore with the appropriate factory and a franchise is good to go.

in code,

NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
nyStore.order(“Veggie”);

ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
PizzaStore chicagoStore = new PizzaStore(chicagoFactory);
chicagoStore.order(“Veggie”);

My questions is, PizzaStore has a dependency on a concret class, which is SimplePizzaFactory, how can we new a PizzaStore with NYPizzaFactory instance or ChicagoPizzaFactory instance?