I'm trying to convert a example code of an eCommerce Application from Java to Python to better understand this principle.
Here is the Java code that has this example:
public class ProductCatalog {
public void listAllProducts() {
ProductRepository productRepository = ProductFactory.create();
List<String> allProductNames = productRepository.getAllProductNames();
// Display product names
}
}
public interface ProductRepository {
public List<String> getAllProductNames();
}
public SQLProductRepository implements ProductRepository {
public List<String> getAllPRoductNames() {
return Arrays.asList("soap", "toothpaste");
}
}
public class ProductFactory {
public static ProductRepository create() {
return new SQLProductRepository();
}
}
My python code is:
import zope.interface
class ProductRespository(zope.interface.Interface):
def getAllProductNames(self) -> list:
pass
@zope.interface.implementer(ProductRespository)
class SQLProductRepository:
def getAllProductNames(self) -> list:
return ["soap", "toothpaste"]
class ProductFactory:
def create(self) -> ProductRespository:
return SQLProductRepository()
class ProductCatalog:
def listAllProducts(self) -> None:
productRespository = ProductRespository()
productRespository = ProductFactory.create()
allProductNames = productRespository.getAllProductNames()
print(allProductNames)
myProductCatalog = ProductCatalog()
myProductCatalog.listAllProducts()
The error is:
Traceback (most recent call last):
File "/Users/me/udemy_courses/solid_principles/5_dependency_invertion.py", line 42, in <module>
myProductCatalog.listAllProducts()
File "/Users/me/udemy_courses/solid_principles/5_dependency_invertion.py", line 35, in listAllProducts
productRespository = ProductFactory.create()
TypeError: ProductFactory.create() missing 1 required positional argument: 'self'
I guess that the problem could be in some creation of class from python or variable declaration, since this language don't need to specify the type of variable.
CodePudding user response:
In the Java code ProductFactory.create
is defined as a static method.
public class ProductFactory {
public static ProductRepository create() { // <-- static
return new SQLProductRepository();
}
}
If you want to mirror that design you need to do so as well in the Python version.
class ProductFactory:
@staticmethod
def create() -> ProductRespository: # note: no "self" argument
return SQLProductRepository()
CodePudding user response:
You need to first call the class (object) and then run the function. OOP works a bit different in Python (I'm not familiar with Java but here's how python gives it a go):
class Person:
def name(self):
print("John")
# Person.name() → Error
Person().name() # Works
Like the above example, simply replace productRespository = ProductFactory.create()
to productRespository = ProductFactory().create()
and it should work. Basically, you need to call the class as well to define self
.