patternjavaMinor
ProductManager: a basic CRUD for products with SQLite
Viewed 0 times
productmanagerwithsqliteforcrudbasicproducts
Problem
I would like to have a review of this basic CRUD application so I can improve and learn from your experience. The code can be found here.
ProductManager.java
```
public class ProductManager {
private IProductDatabase db;
public ProductManager(String Dburl) throws ServiceException {
try {
db = new SQLiteProductDatabase(Dburl);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public int getNumberOfProducts() throws ServiceException{
try {
return db.size();
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public void addProduct(Product product) throws ServiceException {
try {
db.addProduct(product);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public Product getProductByEan(Long ean) throws ServiceException {
try {
return db.getProductByEan(ean);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public Product getProductByHope(int hope) throws ServiceException {
try {
return db.getProductByHope(hope);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public Collection getAllProducts() throws ServiceException {
try {
return db.getAllProducts();
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public void updateProduct(Product product) throws ServiceException {
try {
db.updateProduct(product);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public void deleteProduct(Long ean) throws ServiceException
- Design pattern/coding principles improvement that could be used
- Exception handling
- Readability
- Coding best practices
ProductManager.java
```
public class ProductManager {
private IProductDatabase db;
public ProductManager(String Dburl) throws ServiceException {
try {
db = new SQLiteProductDatabase(Dburl);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public int getNumberOfProducts() throws ServiceException{
try {
return db.size();
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public void addProduct(Product product) throws ServiceException {
try {
db.addProduct(product);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public Product getProductByEan(Long ean) throws ServiceException {
try {
return db.getProductByEan(ean);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public Product getProductByHope(int hope) throws ServiceException {
try {
return db.getProductByHope(hope);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public Collection getAllProducts() throws ServiceException {
try {
return db.getAllProducts();
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public void updateProduct(Product product) throws ServiceException {
try {
db.updateProduct(product);
} catch (DatabaseException ex) {
throw new ServiceException(ex);
}
}
public void deleteProduct(Long ean) throws ServiceException
Solution
I'd like to add a few points to your proposed implementation.
Inversion of control
The first thing I'd change is the constructor of your ProductManager class. I'd pass in an IProductDatabase rather than the connection string. This will make the code more testable as you'd be able to pass in test doubles at 'test time'.
Exception Handling
The other point is regarding exception handling. Usually you want to catch exceptions if you intend to handle them in any way. I'm not sure how much value you get if you just wrap the original exception into another exception. Catching exceptions is somewhat expensive
Validation
I'd also add validation on all the method calls. For example if a null object would passed to the constructor of the ProductManager class, an imediat IllegalARgumentException would be much useful than an eventuall NullPointerException.
I'd also try to use relevant exceptions. For example instead of :
I would use
Instead of :
I'd use
I hope this helps
Inversion of control
The first thing I'd change is the constructor of your ProductManager class. I'd pass in an IProductDatabase rather than the connection string. This will make the code more testable as you'd be able to pass in test doubles at 'test time'.
public class ProductManager {
private IProductDatabase m_db;
public ProductManager(IProductDatabase db) {
m_db =db
}
...
}Exception Handling
The other point is regarding exception handling. Usually you want to catch exceptions if you intend to handle them in any way. I'm not sure how much value you get if you just wrap the original exception into another exception. Catching exceptions is somewhat expensive
Validation
I'd also add validation on all the method calls. For example if a null object would passed to the constructor of the ProductManager class, an imediat IllegalARgumentException would be much useful than an eventuall NullPointerException.
public class ProductManager {
private IProductDatabase m_db;
public ProductManager(IProductDatabase db) {
if(db==null)
{
throw IllegalArgumentException("db");
}
m_db =db
}
...
}I'd also try to use relevant exceptions. For example instead of :
@Override
public void addProduct(Product product) throws DatabaseException {
if (product == null) {
throw new DatabaseException(ErrorMessages.PRODUCT_NULL);
}
...
}I would use
@Override
public void addProduct(Product product) throws DatabaseException {
if (product == null) {
throw new IllegalArgumentException("product");
}
...
}Instead of :
@Override
public Product getProductByHope(int hope) throws DatabaseException {
...
if (product == null) {
throw new DatabaseException(ErrorMessages.PRODUCT_NOT_FOUND_HOPE);
}
}I'd use
@Override
public Product getProductByHope(int hope) throws ProductNotFoundException {
...
if (product == null) {
throw new ProductNotFoundException(ErrorMessages.PRODUCT_NOT_FOUND_HOPE);
}
}I hope this helps
Code Snippets
public class ProductManager {
private IProductDatabase m_db;
public ProductManager(IProductDatabase db) {
m_db =db
}
...
}public class ProductManager {
private IProductDatabase m_db;
public ProductManager(IProductDatabase db) {
if(db==null)
{
throw IllegalArgumentException("db");
}
m_db =db
}
...
}@Override
public void addProduct(Product product) throws DatabaseException {
if (product == null) {
throw new DatabaseException(ErrorMessages.PRODUCT_NULL);
}
...
}@Override
public void addProduct(Product product) throws DatabaseException {
if (product == null) {
throw new IllegalArgumentException("product");
}
...
}@Override
public Product getProductByHope(int hope) throws DatabaseException {
...
if (product == null) {
throw new DatabaseException(ErrorMessages.PRODUCT_NOT_FOUND_HOPE);
}
}Context
StackExchange Code Review Q#103821, answer score: 2
Revisions (0)
No revisions yet.