Improvements in repository pattern I am trying to learn the clean architecture by Uncle Bob. I wanted some basics and following this good post I tried to implement it in python with some minor differences.

class ValidationError(Exception):
    pass


class Repository(object):

    repositories = {}

    @classmethod
    def register(cls, type_, repo):
        cls.repositories[type_] = repo

    @classmethod
    def get(cls, type_):
        return cls.repositories[type_]

    @classmethod
    def all(cls):
        return cls.repositories


class UserValidator(object):

    def validate(self, user):
        if not (user.name and user.email):
            raise ValidationError


class UserRepo(object):

    def __init__(self, validator=None):
        self.users = {}
        self.next_id = 1
        self.validator = validator

    def save(self, user):
        self.validator.validate(user)
        user.id = self.next_id
        self.users[self.next_id] = user
        self.next_id += 1
        return user

    def all(self):
        return self.users

    def get(self, id):
        return self.users[id]

    def delete(self, id):
        return self.users.pop(id)


class CompanyRepo(object):

    def __init__(self):
        self.companies = {}
        self.next_id = 1

    def save(self, company):
        company.id = self.next_id
        self.companies[self.next_id] = company
        self.next_id += 1
        return company

    def all(self):
        return self.companies

    def get(self, id):
        return self.companies[id]

    def delete(self, id):
        return self.companies.pop(id)


class BaseEntity(object):

    def __init__(self):
        self.id = None
        self.created_at = None
        self.updated_at = None


class Company(BaseEntity):

    def __init__(self, name, address):
        self.name = name
        self.address = address
        super(Company, self).__init__()


class User(BaseEntity):

    def __init__(self, name, email):
        self.name = name
        self.email = email
        self.company_id = None
        super(User, self).__init__()

    def serialize(self):
        return {'id': self.id, 'name': self.name, 'email': self.email, 'company_id': self.company_id}

    def value(self):
        return self.serialize()    

class WorkerAdder(object):

    def __init__(self, name, email):
        self.user_repo = Repository.get('user')
        self.company_repo = Repository.get('company')

        self.company = self.company_repo.save(Company('FooBar', 'Dummy street'))
        self.user = User(name, email)

    def add(self):
        try:
            self.user.company_id = self.company.id
            print self.user_repo.save(self.user).value()
            print self.user_repo.all()
            print self.user_repo.get(1)
            print self.company_repo.all()
        except ValidationError as ve:
            print "Validation error!"


if __name__ == '__main__':

    Repository.register('user', UserRepo(validator=UserValidator()))
    Repository.register('company', CompanyRepo())

    adder = WorkerAdder('Foo', 'foo@example.com')
    adder.add()


O/P from above code:

{'company_id': 1, 'email': 'foo@example.com', 'id': 1, 'name': 'Foo'}
{1: &lt;__main__.User object at 0x7f4b34139d50&gt;}
&lt;__main__.User object at 0x7f4b34139d50&gt;
{1: &lt;__main__.Company object at 0x7f4b34139d10&gt;}


I have basically tried to implement the in memory repository pattern. I would like to hear from others what they think, and why there is so scarcity in the python community regarding the design patterns and different architectures as compared to ruby?

PS: The code above is just for learning purpose hence error handling and error cases are not handled properly.
I'm skeptical of the value of this design pattern, for two reasons:


The Repository class is basically just a Python dictionary.  You never use Repository.all() anyway.
Repository is actually a glorified namespace.  It's a disguised mechanism for you to make a bunch of global variables.


Additionally, I see some puzzling aspects to the code:


Why would UserRepo() make its .validator configurable?  And why would it default to None?
Since UserRepo and CompanyRepo contain nearly identical code, why not consolidate them?  At the least they should have a common base class.  Maybe they could even be handled by one class.
The WorkerAdder object seems contrived.  Why split the work between a WorkerAdder() constructor and an .add() method?  Why is the company name and address hard-coded?


Some minor remarks:


It's customary to chain to the superclass constructor first, not as the last statement in the subclass's constructor.
Serialization means turning an object into a string representation; your User.serialize() returns a dictionary instead.  The string representation needs to  contain enough detail to reconstruct the object exactly; your User.serialize() omits the .created_at and .update_at timestamps.


In summary, Repository is just a dictionary that serves as a namespace for global variables.  There's not much point to it, since symbol tables in Python are also dictionaries.  UserRepo and CompanyRepo do serve a purpose, but you would have to reinvent the wheel (implementing the persistence mechanism, for example) to make them useful.  You might as well use a real database (which could be as simple as sqlite) with an ORM.