Reputation: 61
The problem is really simple, I have a class "Stock", I want to load its property "StockName", "StockCode' from the db.
so which patten should I use?
pattern 1) Use service class to create it
public interface IStockService{
Stock GetStock(string stockCode);
void SaveStock(Stock stock);
}
public class StockService : IStockService{
}
IStockService stockService = new StockService();
Stock stock = stockService.GetStock();
pattern 2) Use static method in Stock
public class Stock{
public static Stock GetStock(){
Stock stock = new Stock;
//load stock from db and do mapping.
return stock;
}
public void Save(){
}
}
pattern 3) Use constructor to load
public class Stock{
public Stock(){
//load stock from db and do mapping.
this.stockName = ...
this.stockCode = ...
}
}
for pattern 1: it seems it use so many code to create a stock object, and the "SaveStock" method seems a little not object-orient.
for pattern 2: the "Save" method seems ok, but the GetStock method is a static method, it seems a Utility class which always use static method.
for pattern 3: the constructor will load the data from db when on initialize. it seems confused also.
Upvotes: 6
Views: 2706
Reputation: 9440
pattern 2) is the factory (method) patten and reminds me of singletons (static = singleton). Note singletons are evil. The factory method is not not polymorph. You can't change it for tests (i.e. you can't mock it). It's evil! Avoid it!
pattern 3) violates that the constructor should not do too much. Querying the database is too much for a ctor in my opinion. The object and it's creation are different concerns and should be separated. Further more creation of an instance should be separated from the instance, so try to use factories (or injectors). You can replace the factory easier than the "new Class" spread throught your code.
pattern 1) remains, which is an abstract factory pattern. It is good. You can use another implementation for testing (a mock). It separates the creation from the object. (Single responsibility principle as Carl Bergquist calls it.)
So I would go with pattern 1.
Upvotes: 5
Reputation: 3942
Pattern 1:
- Easier to test
- Single responsibility principle
- Can require more code.
Pattern 2:
- Static classes/methods can make mocking much harder. I try to avoid it as much as I can.
Pattern 3:
- Is ok for small classes. But keep logic away from the constructor
But I think Orm and serialization cover most parts(object creation).
Upvotes: 2
Reputation: 70287
You are missing an important piece. Specifically, where do you get your connection string for talking to the database?
Update each of your examples with where the connection string comes from and I think it will make the right answer pop out.
Upvotes: 1
Reputation: 1706
you should seperate the entity class(stock) and the logic that populates it(stockservice), but instead of writing a stockservice class just use an orm to map db to your entity class(stock).
Upvotes: 0
Reputation: 6146
something similar to method 1 where you should be calling into the DB layer classes to get the object loaded from there, though you may want to use an ORM to take care of all the data access for you
Upvotes: 0
Reputation: 1149
if you want it to be initialized automatically, then use static constructor which been called by class loader .net service.
Upvotes: 0
Reputation: 1038710
I would go with pattern 1. It presents a clear separation of concerns between the domain model and the data access. It is also easier to unit test.
Upvotes: 0
Reputation: 1934
Personally I like have my objects abstracted from their data source, so I'd go with a method like #1. #3 you definitely don't want to do...too much processing in constructors can get you in trouble. The preference of #1 vs #2 is likely to come down to how 'loaded' you want your data objects to be.
If you ever foresee getting your object from another data source you'll want to stick with #1 since it gives much better flexibility.
Upvotes: 0