开发者

why do some patterns have classes with seperate data classes in oo design

开发者 https://www.devze.com 2023-04-05 03:28 出处:网络
I have just been reading over some of my old oo design books and something that I dont quite follow. If im using somet开发者_C百科hing like the repository pattern lets say.

I have just been reading over some of my old oo design books and something that I dont quite follow.

If im using somet开发者_C百科hing like the repository pattern lets say.

i.e:

    interface ICarRepository {

      IEnumerable<car> GetCarCollection();

    }

    class MsSqlCarRepository : ICarRepository {

      IEnumerable<car> GetCarcollection(){ ................ };

    }

    class car {

      int CarId;
      string CarName;

    }

The above code is roughly c# but isnt really relevant.

Although the above works well and is what I generally see and use myself, All the books I read about oo generally state that an object combines its Methods and Properties togeather.

So Ignoring the interface part shouldnt it be more along the lines of:

    class car {

      int CarId;
      string CarName;

      IEnumerable<car> GetCarcollection(){ ................ };

    }

????


It's all about coupling between the layers of different parts of your code. Separating your domain models from the operations/contracts that could be performed on those domain models allows you to reuse those domain models more easily in other contexts. Imagine for example that someone wants to define some other operations with this Car model than GetCarcollection. In this case he would write a different repository interface and you won't need to modify this domain model. On the other hand if you defined the GetCarcollection method inside the Car object this other consumer of the model won't be happy as he might not care about your method but would like to use his own.


The idea is so that you can substitute for a different repository eg PostgresSQLCarRepository without needing to change your Car class.

You could use this where you seperate out your repository classes into a seperate library and then load them by Dependency Injection.

So if you compiled multiple libary dlls, one that talks postgres, one that talks mssql, one that talks XML you could use any of them with your code without worrying about recompiling your car classes.

--EDIT After Comment

After the additional comments the question appears to be more why does this real wolrd design pattern appear to not follow the basic principles of OO?

The short answer is it does follow the basic principles of OO.

The long answer...

The basic idea of the OO (And this is overly simplistic without going into massive amounts of inheritance, polymorphism etc) is that you group together a collection of properties about a specific entity and methods that operate on a specific entity into a single class.

The GetCarCollection() method does not apply to a single car instance. It applies to the Repository, because you are asking the repository to return a collection of cars. However a method like Start() may be method against a car because it would apply specifically to that one car instance.

On top of that you additionally have properties that could be readonly and you usually hide the backing fields to be only accessible to class instance itself so instead you might have

public class car { 

  private int _carId; 
  private string _carName; 
  private int speed=0;

  public Car(int carId) {
    this._carId=carId;
  }

  public int CarId {
    get { return this._carId; } 
  }

  public string  CarName {
    get { return this._carName; }
    set { this._carName=value; }
  }

  public int Speed {
    get { return this._speed; }
  }

  public void Accelerate() {
    if (this._speed<91) this._speed++;
  }
} 

public class MsSqlCarRepository : ICarRepository {    

  public MsSqlCarRepository(SqlConnection conn) {.....}

  IEnumerable<car> GetCarcollection(){ ................ }

}    

public class XmlCarRepository : ICarRepository {    

  public XmlCarRepository(string FileName) {.....}

  IEnumerable<car> GetCarcollection(){ ................ }

}    

The example you gave may have not seemed very OO to you, but it was more because it was simplistic. As the level of detailed and complexity to your objects increases you should see how this is in fact an OO approach and starts to diverge from you C struct and manager approach.


A 'car collection' isn't an intrinsic property of a car. A garage or a car-park might have a car collection.


The car is not a car-repository. Otherwise you'd need to have a car to get a car.

GetCarCollection could be a static method, but that then wouldn't allow you to mock or inject the repository, and doesn't represent separation of concerns (i.e. Is the role of the type to represent a car? Or is it to fetch cars?).

Where to draw the line here is subjective, and may vary on project requirements.

0

精彩评论

暂无评论...
验证码 换一张
取 消