How to decouple two classes elegantly in the following example? - oop

Suppose we take the case of building a Vending machine using OOP principles.
Let us suppose we have an abstraction called VendingMachine.
class VendingMachine {
List<Slot> slots; //or perhaps a 2-d matrix of slots
}
The VendingMachine class has a list of slots and each slot may have some capacity (to model say 5 items one behind the other).
Now how do I associate a Value ($) to a slot. Clearly each slot will have the same item so each slot should be associated with same value (or better an abstraction representing the item, say Item class).
But in terms of responsibility, the VendingMachine class should only be able to eject an item, or throw an exception when trying to eject an item from an empty slot. I think that it is not the responsibility of VendingMachine class to know what is the value of a particular slot.
How do I design this elegantly? Is there some design pattern that comes to your mind.
My solution is to create a class MoneyManager.
class MoneyManager {
MoneyManager(VendingMachine vm);
Pair<Slot, Item> mapping;
}
class Item {
int itemCode;
BigDecimal value;
}
Even if you think that the modelling is wrong, what I am more interested in knowing is how do you decouple 2 classes like that.
For example if you design a car parking lot, a class Vehicles should have information on how much space it takes (number of spots). A ParkingLot has information how much spots it has.
But I don't want the car to know in which ParkingLot it is parked and in which spot. Similarly I don't want the ParkingLot to maintain the state of what cars are parked and where. Should there be an intermediate class ParkingManager which maintains this state for a clean design?

I think what you need is some kind of logic like a wharehouse administration.
Supposing all the slots and items are of the same size, you could probabbly break it out like this.
public class Item
{
public string Name { get; set; }
public string Category { get; set; }
}
public class Slot
{
public int Capacity { get; set; }
public List<Item> Items { get; set; }
}
public class Warehouse
{
public List<Slot> Slots { get; set; }
}
This is going to manage the basic distribution of the items in the warehouse. Warehouse class is going to manage the list of slots and Slot class is going to manage the list of items it contains.
Probably, if you need, you could add sizes and locations and add some logic of what kind of items fit the different slots.

Related

How to handle DAL for multiple layers of 1 to many relationship?

I have the following problem:
I have an aggregate root with multiple layers of one to many relationship.
Root -> has many
Child -> has many
GrandChild
I have Controller\s that handle logic done on each layer of the aggregate root.
I do not know how to handle the data access layer.
Should i just create a repository for the aggregate root and all Child and GrandChild operations get handled through it or it would be fine to create a repository for every level ?
Furthermore the GrandChildren entities in my case occupy a lot of space (they contain text) , thus i will be using a document database - RavenDB.
public class Root
{
public int ID{get;set;}
public IEnumerable<Child>Children;
}
public class Child
{
public int ChildID{get;set;}
public IEnumerable<Child>GrandChildren; //occupy a loot of space !
}
public class GrandChild
{
public int GrandChildID{get;set;}
}
public interface IGenericRepository<T>
{
bool Add<T>(T newValue);
T Get<T>(int id);
IEnumerable<T> GetAll();
bool Delete(int id);
bool Update<T>(T value);
}
Controller
public class ParentController
{
IGenericRepository<Root> repo;
public IActionResult<Root> Get(int rootId)
{
return this.repo.Get(rootId);
}
}
public class ChildControiller_V1
{
IGenericRepository<Child>repo;
public IActionResult<Child> Get(int childid)
{
this.repo.Get(childid); //the id is unique
}
}
Access through root
public class RootRepository:IGenericRepository<Root>
{
/// implementations
public IGenericRepository<Child> GetChildRepository()
{
return //some implementation of IGenericRepository for Child
}
}
public class ChildController_V2
{
IGenericRepository<Root>repo;
public IActionResult<Child> Get(int rootId,int childid)
{
var root=this.repo.Get(rootId);
var childRepo=root.GetChildRepository();
var get= childRepo.Get(childId);
}
}
I hope you get the idea.For more layers i would do this all the way down.What would be a good approach considering the lowest entities occupy a lot of space compared to the others?
Update
The Root will have to support Create,Delete - not much happening here
The Child will have to support Create,Delete - (The focus will be on GET
, something like GET 5 children starting from index=10 here)
The Grandchildren will have to support full CRUD with a heavy intensive work on Update .Their table size of GrandChildren will be >>>>> all the others combined.Every Grandchild will have a plain text column.
When i say table or column i am referring to their equivalent in a typical SQ L database
From a (classic)DDD point of view, repositories return fully materialized aggregates, where aggregates represent consistency/transactional boundaries. Having children and grandchildren repositories means you give that up and with it a big benefit of DDD. That being said, you need to determine where your consistency boundaries are. Are there constraints between the entities? If not, they can be there own aggregates. Remember that aggregates don't appear in other aggregates and references from an entity should only go to an aggregate root, not some other entity in another aggregates' hierarchy.
I already mentioned a few other points that may be interesting in my answer here, specifically a direction if the data is too much.
https://stackoverflow.com/a/59189413/2613363
Lastly, I will say Raven has versions (etags). Use them if you end up updating many child items.

Object-Oriented Programming: How to properly design, implement, and name a method which involve object interactions?

Language doesn't matter, it is generic object-oriented question(take java/C# etc). Take a simple concept.
A Person has a Car. The Person can drive the Car. Car doesn't usually drive or wander around, right? ``
But, usually in codes, we see methods like myCarObject.Drive().
Now when a Person is introduced, and the Person drives the car:
======================= First Way =================================
class Car{
int odometer;void drive(){ odometer++; }
}
class Person{
void driveCar(Car c) { c.drive(); }
}
========================================================================
================================ Alternative Way =======================
public Car{
int odometer; // car doesn't do the driving, it's the person, so no drive()
}
public Person{
void driveCar(Car c) { c.odometer++; }
}
========================== and other ways....============================
===========================================================================
So, my question is clear: what is the best way to design/implement/name methods in similar cases?
It's a bit difficult to make simplified examples like that make any sense, but here is an attemt:
A Car class would generally contain methods for the things that the object can do by itself with the information that it has, for example:
public class Car {
private bool engineOn;
public int Speed { get; private set; }
public void Start() { engineOn = true; Speed = 0; }
public void Accelerate() { Speed++; }
public void Break() { if (Speed > 0) Speed--; }
public void Stop() { Speed = 0; engineOn = false; };
}
A Person class would would manage a car by controlling the things that the car itself is not aware of in its environment. Example:
public class Person {
public void Drive(Car car, int speedLimit) {
car.Start();
while (car.Speed < speedLimit) {
car.Accelerate();
}
while (car.Speed > 0) {
car.Break();
}
car.Stop();
}
}
There are of course many different variations of how you can use OO in each situation.
If you wish to express your logic in a way that closely resembles human language semantics, you'll want to invoke an action or function on an entity which is logically capable of carrying it out.
When behavior cannot be placed on an object (in the sense that it has state), you put it in a Service or Utility class, or some similar construct. Authenticate is a classic example of something that doesn't make much sense to invoke on a user, or on any other object. For this purpose, we create an AuthenticationProvider (or service, whichever you prefer).
In your scenario of a Person and a Car, it's one object invoking behavior on another. person.Drive(car) would therefore make the most sense.
If a Person owns a Car (and a Car is always owned by a Person), then person.Drive() might be the only thing you need to do. The Drive() method will have access to the properties of person, one of which is its car.
An important thing to note here is the concept of loose coupling. In more complex scenario's, you don't want to all sorts of cross-references within your model. But by using interfaces and abstractions you'll often find yourself putting methods on objects where they don't really belong from a real-world perspective. The trick is to be aware of, and utilize a language's features for achieving loose coupling and realistic semantics simultaneously.
Keeping in mind that in a real application you'll have the bootstrapping code tucked away elsewhere, here is an example of how that might look like in C#:
We start off by defining interfaces for the things that can transport (ITransporter), and the things that can be transported (ITransportable):
public interface ITransportable
{
void Transport(Transportation offset);
}
public interface ITransporter
{
void StartTransportation(ITransportable transportable);
void StopTransportation(ITransportable transportable);
}
Note the Transportation helper class which contains the information necessary to re-calculate the current location of an ITransportable after it has been transported for a certain period of time with a certain velocity and whatnot. A simple example:
public class Transportation
{
public double Velocity { get; set; }
public TimeSpan Duration { get; set; }
}
We then proceed to create our implementations for these. As you might have guessed, Person will derive from ITransportable and Car derives from ITransporter:
public class Person : ITransportable
{
public Tuple<double, double> Location { get; set; }
private ITransporter _transporter;
void ITransportable.Transport(Transportation offset)
{
// Set new location based on the offset passed in by the car
}
public void Drive<TCar>(TCar car) where TCar : ITransporter
{
car.StartTransportation(this);
_transporter = car;
}
public void StopDriving()
{
if (_transporter != null)
{
_transporter.StopTransportation(this);
}
}
}
Pay close attention to what I did there. I provided an explicit interface implementation on the Person class. What this means is that Transport can only be invoked when the person is actually referenced as an ITransportable - if you reference it as a Person, only the Drive and StopDriving methods are visible.
Now the Car:
public class Car : ITransporter
{
public double MaxVelocity { get; set; }
public double Acceleration { get; set; }
public string FuelType { get; set; }
private Dictionary<ITransportable, DateTime> _transportations = new Dictionary<ITransportable, DateTime>();
void ITransporter.StartTransportation(ITransportable transportable)
{
_transportations.Add(transportable, DateTime.UtcNow);
}
void ITransporter.StopTransportation(ITransportable transportable)
{
if (_transportations.ContainsKey(transportable))
{
DateTime startTime = _transportations[transportable];
TimeSpan duration = DateTime.UtcNow - startTime;
var offset = new Transportation
{
Duration = duration,
Velocity = Math.Max((Acceleration*duration.Seconds), MaxVelocity)/2
};
transportable.Transport(offset);
_transportations.Remove(transportable);
}
}
}
Following the guidelines we set earlier, a Car will not have any (visible) methods on it, either. Unless you explicitly reference it as an ITransporter, which is exactly what happens inside of the Person's Drive and StopDriving methods.
So a Car here is just a Car. It has some properties, just like a real car, based on which you can determine a location offset after a person drove it for a certain amount of time. A Car cannot "Drive", "Start", or anything like that. A Person does that to a Car - a Car does not do that to itself.
To make it more realistic you would have to add all sorts of additional metadata that affect a Car's average velocity over a certain period of time on a certain route. Truth is, you probably won't end up modeling something like this anyway. I stuck with your model just to illustrate how you could retain natural language semantics if you were working with objects that make it challenging to do so.
An example of how these classes may be used by a client:
Person person = new Person();
Car car = new Car();
// car.Transport(); will not compile unless we explicitly
// cast it to an ITransporter first.
// The only thing we can do to set things in motion (no pun intended)
// is invoke person.Drive(car);
person.Drive(car);
// some time passes..
person.StopDriving();
// currentLocation should now be updated because the Car
// passed a Transportation object to the Person with information
// about how quickly it moved and for how long.
var currentLocation = person.Location;
As I already eluded before, this is by no means a good implementation of this particular scenario. It should, however, illustrate the concept of how to solve your problem: to keep the logic of "transportation" inside of the "transporter", without the need to expose that logic through public methods. This gives you natural language semantics in your client code while retaining proper separation of concerns.
Sometimes you just need to be creative with the tools you have.
In second case, it's like you're saying that the task of driving a car consist in incrementing the odometer. It's clearly not the driver's business, and a violation of encapsulation. The odometer should probably be an implementation detail.
In first case, the car maybe does not drive itself, but it advances, so you could use another verb. But car.advance() is maybe not how a Person drives cars... Even if it was thru vocal commands, the decoding of the command would probably result in a sequence of more basic commands.
I very much like the answer of Guffa which tries to address what driving a car could mean. But of course, you may have another context...

Do I have to implement Add/Delete methods in my NHibernate entities?

This is a sample from the Fluent NHibernate website:
Compared to the Entitiy Framework I have ADD methods in my POCO in this code sample using NHibernate. With the EF I did context.Add or context.AddObject etc... the context had the methods to put one entity into the others entity collection!
Do I really have to implement Add/Delete/Update methods (I do not mean the real database CRUD operations!) in a NHibernate entity ?
public class Store
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public virtual IList<Employee> Staff { get; set; }
public Store()
{
Products = new List<Product>();
Staff = new List<Employee>();
}
public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add(this);
Products.Add(product);
}
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
}
}
You don't have to do this for nhibernate, you have to do this for keep in-memory consistence and not repeat yourself.
Consistence in memory
If you have a two way relationship, lets say Order has Lines, and Line as a relationship to order. You don't want to have a reference from one side and not from the other.
If you just do:
order.Lines.Add(line);
You have made a reference from Order to Line, but Line.Order property remains null. So your in-memory instances are not consistent.
Don't Repeat Yourself
You can use the following code :
order.Lines.Add(line);
line.Order = order;
but you will be repeating yourself, so it is better to put this code in only one place, and the best place is as order.AddLine(..).
You don't have to. You could just call SomeStore.Products.Add(someProduct) directly from outside of your entity. But it's often good practice to make the collections 'read-only' from a public perspective, and using an add method in the entity for adding items.
One benefit of this is that you can put additional logic in there. For instance in your store example, you could set a 'storesStockedIn' collection (if there was such a thing) in the same method, and so keep all the logic about to creating that relationship in one place.
This isn't really a NHibernate thing, but rather an OOP thing. (Although I'm not familiar with EF - maybe it automates some of this for you). The design decisions are exactly the same as if it was just an unpersisted poco (without NHibernate).

Object Oriented Design for a Chess game [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am trying to get a feel of how to design and think in an Object Oriented manner and want to get some feedback from the community on this topic. The following is an example of a chess game that I wish to design in an OO manner. This is a very broad design and my focus at this stage is just to identify who is responsible for what messages and how the objects interact each other to simulate the game. Please point out if there are elements of bad design (high coupling, bad cohesion etc.) and how to improve on them.
The Chess game has the following classes
Board
Player
Piece
Square
ChessGame
The Board is made up of squares and so Board can be made responsible for creating and managing Square objects. Each piece also is on a square so each piece also has a reference to the square it is on. (Does this make sense?). Each piece then is responsible to move itself from one square to another.
Player class holds references to all pieces he owns and is also responsible for their creation (Should player create Pieces?) . Player has a method takeTurn which in turn calls a method movePiece which belongs to the piece Class which changes the location of the piece from its current location to another location. Now I am confused on what exactly the Board class must be responsible for. I assumed it was needed to determine the current state of the game and know when the game is over. But when a piece changes it's location how should the board get updated? should it maintain a seperate array of squares on which pieces exist and that gets updates as pieces move?
Also, ChessGame intially creates the Board and player objects who in turn create squares and pieces respectively and start the simulation. Briefly, this might be what the code in ChessGame may look like
Player p1 =new Player();
Player p2 = new Player();
Board b = new Board();
while(b.isGameOver())
{
p1.takeTurn(); // calls movePiece on the Piece object
p2.takeTurn();
}
I am unclear on how the state of the board will get updated. Should piece have a reference to board? Where should be the responsibility lie? Who holds what references? Please help me with your inputs and point out problems in this design. I am deliberately not focusing on any algorithms or further details of game play as I am only interested in the design aspect. I hope this community can provide valuable insights.
I actually just wrote a full C# implementation of a chess board, pieces, rules, etc. Here's roughly how I modeled it (actual implementation removed since I don't want to take all the fun out of your coding):
public enum PieceType {
None, Pawn, Knight, Bishop, Rook, Queen, King
}
public enum PieceColor {
White, Black
}
public struct Piece {
public PieceType Type { get; set; }
public PieceColor Color { get; set; }
}
public struct Square {
public int X { get; set; }
public int Y { get; set; }
public static implicit operator Square(string str) {
// Parses strings like "a1" so you can write "a1" in code instead
// of new Square(0, 0)
}
}
public class Board {
private Piece[,] board;
public Piece this[Square square] { get; set; }
public Board Clone() { ... }
}
public class Move {
public Square From { get; }
public Square To { get; }
public Piece PieceMoved { get; }
public Piece PieceCaptured { get; }
public PieceType Promotion { get; }
public string AlgebraicNotation { get; }
}
public class Game {
public Board Board { get; }
public IList<Move> Movelist { get; }
public PieceType Turn { get; set; }
public Square? DoublePawnPush { get; set; } // Used for tracking valid en passant captures
public int Halfmoves { get; set; }
public bool CanWhiteCastleA { get; set; }
public bool CanWhiteCastleH { get; set; }
public bool CanBlackCastleA { get; set; }
public bool CanBlackCastleH { get; set; }
}
public interface IGameRules {
// ....
}
The basic idea is that Game/Board/etc simply store the state of the game. You can manipulate them to e.g. set up a position, if that's what you want. I have a class that implements my IGameRules interface that is responsible for:
Determining what moves are valid, including castling and en passant.
Determining if a specific move is valid.
Determining when players are in check/checkmate/stalemate.
Executing moves.
Separating the rules from the game/board classes also means you can implement variants relatively easily. All methods of the rules interface take a Game object which they can inspect to determine which moves are valid.
Note that I do not store player information on Game. I have a separate class Table that is responsible for storing game metadata such as who was playing, when the game took place, etc.
EDIT: Note that the purpose of this answer isn't really to give you template code you can fill out -- my code actually has a bit more information stored on each item, more methods, etc. The purpose is to guide you towards the goal you're trying to achieve.
Here is my idea, for a fairly basic chess game :
class GameBoard {
IPiece config[8][8];
init {
createAndPlacePieces("Black");
createAndPlacePieces("White");
setTurn("Black");
}
createAndPlacePieces(color) {
//generate pieces using a factory method
//for e.g. config[1][0] = PieceFactory("Pawn",color);
}
setTurn(color) {
turn = color;
}
move(fromPt,toPt) {
if(getPcAt(fromPt).color == turn) {
toPtHasOppositeColorPiece = getPcAt(toPt) != null && getPcAt(toPt).color != turn;
possiblePath = getPcAt(fromPt).generatePossiblePath(fromPt,toPt,toPtHasOppositeColorPiece);
if(possiblePath != NULL) {
traversePath();
changeTurn();
}
}
}
}
Interface IPiece {
function generatePossiblePath(fromPt,toPt,toPtHasEnemy);
}
class PawnPiece implements IPiece{
function generatePossiblePath(fromPt,toPt,toPtHasEnemy) {
return an array of points if such a path is possible
else return null;
}
}
class ElephantPiece implements IPiece {....}
I recently created a chess program in PHP (website click here, source click here) and I made it object oriented. Here are the classes I used.
ChessRulebook (static) - I put all my generate_legal_moves() code in here. That method is given a board, whose turn it is, and some variables to set the level of detail of the output, and it generates all the legal moves for that position. It returns a list of ChessMoves.
ChessMove - Stores everything needed to create algebraic notation, including starting square, ending square, color, piece type, capture, check, checkmate, promotion piece type, and en passant. Optional additional variables include disambiguation (for moves like Rae4), castling, and board.
ChessBoard - Stores the same information as a Chess FEN, including an 8x8 array representing the squares and storing the ChessPieces, whose turn it is, en passant target square, castling rights, halfmove clock, and fullmove clock.
ChessPiece - Stores piece type, color, square, and piece value (for example, pawn = 1, knight = 3, rook = 5, etc.)
ChessSquare - Stores the rank and file, as ints.
I am currently trying to turn this code into a chess A.I., so it needs to be FAST. I've optimized the generate_legal_moves() function from 1500ms to 8ms, and am still working on it. Lessons I learned from that are...
Do not store an entire ChessBoard in every ChessMove by default. Only store the board in the move when needed.
Use primitive types such as int when possible. That is why ChessSquare stores rank and file as int, rather than also storing an alphanumeric string with human readable chess square notation such as "a4".
The program creates tens of thousands of ChessSquares when searching the move tree. I will probably refactor the program to not use ChessSquares, which should give a speed boost.
Do not calculate any unnecessary variables in your classes. Originally, calculating the FEN in each of my ChessBoards was really killing the program's speed. I had to find this out with a profiler.
I know this is old, but hopefully it helps somebody. Good luck!

DDD confused with Repository Pattern and Reports

I am new to DDD and the Repository pattern, so my understanding of it might be totally wrong. But I am trying to learn it. Having said that I need to create an application, which shows the zones of a store. I create a ZoneRepository for that purpose, which works so far with my few methods. Now in that application I also need to show the distinct styles for that store. The list of styles will be used to drag them into the individual zones. Now my question is where does the styles class belong to, since its kind of a mini-report. Does that "StyleReport" belong into the repository? Does it belong somewhere else? How you know where it belongs to? Please help me to understand.
Repositories only act on Aggregate Roots. Aggregates are a boundary around one or more objects that are treated as a unit. By that I mean, when you operate on that data (inserting, updating, deleting, etc.), all of the objects within that boundary are affected accordingly. Every aggregate has a root. This root is what is referenced externally by other parts of the software. I guess one way to describe it is "something that doesn't rely on something else".
It's a little challenging to derive the proper definition of your domain from a description of your existing models. Furthermore, the design should be based on the business model and needs, not how your UI or application works. So, you should model it on the general problem you are solving, not on how you think you'd like to solve it.
It sounds like you have an entity Store. A Store can be divided up into one or more Zones. Each Zone then has one or more StyleReports. It sounds to me like the Zones are dependent on a Store, so the Store is the aggregate root. Now, perhaps these StyleReport entities are a global set of objects that you offer in your problem domain (meaning you define the StyleReports separately, application-wide, and refer to them in your Zones). In that case, perhaps StyleReport is also an aggregate root.
Here are some example models (C#, not sure what language you're using). However, don't take this as the absolute word. If I don't know the specifics about your domain, I can't very well model it.
public class Store
{
public Int32 ID { get; }
public String Name { get; set; }
public IList<Zone> Zones { get; private set; }
public Store()
{
Zones = new List<Zone>();
}
public void AddZone(Zone zone)
{
Zones.Add(zone);
}
}
public class Zone
{
public Int32 ID { get; }
public String Name { get; set; }
public IList<StyleReport> Styles { get; private set; }
public Zone()
{
Styles = new List<StyleReport>();
}
public void AddStyle(StyleReport style)
{
Styles.Add(style);
}
}
public class StoreRepository : Repository<Store>
{
public Store Get(Int32 id)
{
// get store from persistence layer
}
// find, delete, save, update, etc.
}
public class StyleReportRepository : Repository<StyleReport>
{
public StyleReport Get(Int32 id)
{
// get style from persistence layer
}
// find, delete, save, update, etc.
}
And so when modifying a store's zones and adding styles, maybe something like this
IRepository<Store> storeRepository = new StoreRepository();
IRepository<StyleReport> stylesRepository = new StyleReportRepository();
Store store = storeRepository.Get(storeID); // store id selected from UI or whatever
// add a zone to the store
Zone someZone = new Zone { Name = zoneNamea }; // zone name was entered by the UI
someZone.AddStyle(styleRepository.Get(styleID)); // style id was selected from UI
storeRepository.Update(store);