I am wondering if there are patterns, references or useful resources about how to implement objects that may have several equivalent representations. For example:
Suppose I want to implement a Rectangle
, and I will instantiate it using its length
and width
:
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
and suppose now I also want to have the possibility to instantiate the Rectangle
using its diagonal
and area
. My main concern is that I don't want to store redundant information in the object (in this case, these four properties), only the bare minimum possible to define it.
Suppose too I might want to retrieve one set of properties having created the Rectangle
using another:
r = Rectangle(length=3, width=4)
assert r.diagonal == 5
This is what I've tried so far:
class Rectangle:
def __init__(self, **kwargs):
params = set(kwargs.keys())
if params == set(['length', 'width']):
self._length = kwargs['length']
self._width = kwargs['width']
elif params == set(['area', 'diagonal']):
self._area = kwargs['area']
self._diagonal = kwargs['diagonal']
else:
raise ValueError('Invalid input arguments')
@property
def length(self):
if hasattr(self, '_length'):
return self._length
elif hasattr(self, '_area') and hasattr(self, '_diagonal'):
length, width = ad2lw(self._area, self._diagonal)
#r = Rectangle(length=length, width=width)
#return r._length
return length
else:
raise NotImplementedError('No converter available')
# Same with other three properties
def ad2lw(area, diagonal):
# Obscure math
return l, w
Is this any known pattern or is there a standard way to do it?