views:

174

answers:

8

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.

A: 

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

BlackTigerX
A: 

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.

popester
A: 

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.

Darin Dimitrov
A: 

if you want it to be initialized automatically, then use static constructor which been called by class loader .net service.

amr osama
+4  A: 

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.

Peter Kofler
Factory patterns generally use static methods though. In instance 1 here, a class is initialised only to allow it to use an interface. There are no class variables, so it could easily be rewritten to be static.
ck
IStockService is an abstract factory pattern has no statics. I would not have any statics if I can help it.
Peter Kofler
A: 

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).

Numenor
+1  A: 

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.

Jonathan Allen
+2  A: 

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).

Carl Bergquist