OOP Design for an Economy - oop

Not sure where to start, so I'm just going to plow in. Let's say I'm trying to represent an economy in OOP. A basic design I've come up with is:
class Person{
int $money; // Money someone has in wallet/purse
int $bank_account_id;
function getAmountOfMoney()
function addMoney($amountToAdd)
function subtractMoney($amountToSubtract)
}
class BankAccount{
int $money; // Money in Bank Account
int $interest_per_year;
function giveInterest()
function depositMoney() // Calls $person->subtractMoney()
function withdrawMoney() // Calls $person->addMoney()
}
Are there any design flaws here?

Looking at what you've started with I would suggest that you should try to keep your classes to having a single responsibility. Some food for thought is it the BankAccount that is responsible for calculating interest? Probably not.
If you want to learn good principles on OO development I'd suggest looking at S.O.L.I.D: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod (+100's of other links)

One thing I notice right off, is that a person and a bank account aren't a 1 to 1 relationship. Savings and Chequeing account, right off, for example. Or some people would have multiple banks, or I know like my parents, several accounts with the same bank. Storing the $bank_account_id in Person is what I'm referring to.
It would be better to have an array containing every account the person has.
Also, if you have the ID in Person, you should probably have it in BankAccount as well.
Similar thing with depositMoney() and withdrawMoney(), you have them working on Person, when they should be working on themselves, with Person accessing BankAccount not the other way around.
Basically, you have the relationship between the two classes somewhat backwards from how it would be to represent a real-life (and practical) usage.

Related

Why does class Money extend Expression in Kent Beck's TDD by Example?

I'm studying TDD by Example and up so far I'm finding it a great book. But there's a point where he tells us to write:
// in class Money:
Expression plus(Money addend) {
return new Money(amount + addend.amount, currency);
}
Which won't build unless we declare:
class Money implements Expression {...
This doesn't really make sense to me. Author created Expression as an interface for Sum and Money has nothing in common with Sum. Later on he adds method reduce() in common to both classes, but reduce in Money merely returns this.
Making Money implement Expression is only the path of least effort for removing the error from the plus() method, but it fills the code with unnecessary information (it will have to implement reduce() because of this decision) and increases entropy.
I haven't given it much of a thought, but wouldn't it be cleaner to do something such as this?
class Money {
Money plus(Money addend) {
return new Money(amount + addend.amount, currency).reduce();
}
}
// edited this, it previously returned Expression
Edit:
In the following chapter, author implements a reduce() method in another class (named Bank), which converts Money in between currencies. I still find this to be a weird solution, Sum and Expression names imply we should have a conversion expression class for this task instead. What the author is likely intending to do is to use recursion to add money in different currencies. Either way, it seems to me that he did some far-ahead planning which seems incompatible with TDD as is presented in the book.
On planning ahead
TDD doesn't prohibit planning ahead. The process is about getting rapid feedback on your plans instead of wasting days (or weeks) creating elaborate plans, only to see them 'not survive contact with reality' (to paraphrase Helmuth von Moltke). It's okay to think ahead.
Still, Kent Beck reveals in chapter 17 that this isn't his first rodeo:
"I have programmed money in production at least three times that I can think of. I have used it as an example in print another half-dozen times. I have programmed it live on stage [...] another fifteen times. I coded another three or four times preparing for writing [...] Then, while I was writing this, I thought of using expression as a metaphor and the design went in a completely different direction than before."
So, if you think that he's cheating: yes, he is. He's open about it, though. I think that the motivation was to present a compelling example. He also writes that it was in part based on early reviews of the book.
On the API
That doesn't explain why the code looks like it does, but there's a reason for that. It's actually a nice API.
Why can't you write something like return new Expression(amount + addend.amount, currency).reduce()?
You can't because the reduce method isn't nullary. It takes arguments. You must supply both a bank (which holds the currency conversion rates) and a destination currency.
Keep in mind the problem being solved by the code. People get this wrong all the time, and I think that Kent Beck (inadvertently) fuelled the confusion by naming the example Money.
The problem isn't to model money, but to model investment portfolios in different currencies. If you have a portfolio of 25.000 USD and 10.000 CHF, reducing it to a single currency hides important details. With a portfolio in multiple currencies you diversify risk. Portfolio owners will want to see more than one view of their portfolios. Sometimes, they want to see the portfolio grouped by currency, and at other times they want to see 'the current total worth' of the portfolio presented in a single currency.
The API in the book enables both views.
The reason the underlying 'metaphor' is called an expression is that the API is just a specialised expression tree. It turns out fairly well, though, because it's lawful. Restricted to the sub-types presented in the book, it informally gives rise to a monoid.

Object condition in multiple places/repeated code (DRY)

This is a fundamental application design question I’ve struggled with and flip-flopped on for years. We have a legacy webapp that doesn't really have a solid ORM, if that tidbit might influence your answer. To abstract my question let’s say we have a class Car, and a corresponding table in our database named car. Car has a few properties: color, weight, year, maxspeed These properties directly correspond to columns in the db table.
In our application, we define the car as “classic old” if year is < 1960 and color = black. And in many places within our app knowing whether the car is "classic old" is extremely important (maybe we’re running a very illogical insurance agency which gives steep discounts and other perks to cars which are “classic old”).
All over our application, we do things like:
--list all classic old cars
--give the current user a discount if their car is classic old
--list all classic old cars with max speed > 100 miles per hour
--email the current user if their car is classic old and weights more than 1000 pounds
What is the best way to go about this? We have a legacy application that does this in some places:
getOldClassicCars()
select * where year < 1960 and color = black
and in other places:
cararray = getAllCars();
for each car in cararray
if car.year < 1960 and car.color = black
oldcararray = car.add()
The point being that this very important, fundamental piece of our application – is the car classic old – is “hardcoded” as year < 1960 and color = black in many places. Sometimes in SQL, sometimes in application code, etc. Obviously that is not good, but as we’ve refactored things I’m not sure we’re refactoring things the best way we can.
Well, you are stuck with the fundamental problem that
you cant run your code on the database
you want to be able to use the database's selection functionality on this criteria.
you want the calculation of "classic old" to be defined in a single place (preferably code)
Lets enumerate the solutions
1: Put the calculation in a sproc and always use the sproc to retrieve cars.
The problem here is if you create a new car in code, its class status is undefined, so you haven't really solved the 'not in two places' problem.
2: Get the DB to run your calc via an assembly. for example you can get mssql to run functions from a .net assembly which you can also use in your code base to perform the same calculation.
Problem, its hard work. Plus essentially its still in two places, you have to keep the db up to date and ensure that the table is accessed correctly
3: Persist the calculated value on the DB, but perform the calc in the code
Problem, if the calculation changes the DB values will be incorrect and need updating.
3 seems to be the best option, as we will know when the calculation changes and be able to take some action to resolve the situation.
However, it might be best, given the fundamental nature of this calculation, to make that 'out of dateness' implicit in the way we structure the code.
Instead of simply persisting car.IsClassic we could add a CarStatusReport object with a datetime property. We then generate a CarStatusReport(2017) which evaluates all the cars at that point in time and saves that data in a separate table.
Our business logic is then no longer, "Is this car a classic?" but "What does the latest CarStatusReport say the status of this car is?"
You Business Logic will then reside in a single CarStatusReportGenerator service and any other logic accessing the IsClassic calculation, will be forced to acknowledge the ephemeral nature of the stored info.
No optimal solution here. But, one good point will be to move all the business logic into the one place. If you can't (when you make methods or functions calculating some property, for example isOld()) then hide all those inconsistencies under the hood, so implementation users (conceptually) will never notice DRY violation from outside.

O.O.P and Class Properties

I'm new to O.O.P and would like advice on best practice.
Say for example I have a Course class which holds course information, and a Location class which holds location details. Classes have corresponding repository classes. Now, each Course HAS A location which I have added Location as a property.
When I am pulling the details of a Course from the database, is it best practice to:
A – Populate the Location object from within the CourseRepository Class meaning SQL would return both course and location details
B – Only populate Course object, returning the Location ID, then use the LocationRepository class to find the location details
I’m leaning more towards B as this is a separation of responsibility, however, the thing that’s getting me is performance. Say I need a List instead which returns a result of 50. Would it be wise to query SQL 50 times to seek location details? Would appreciate your thoughts on this.
Lewis
In part, you're thinking in a wrong conceptual direction. It should be: one location can have many courses, not the reciprocal.
That said, theoretical, a Course domain object should not contain a location as class member, but just a location id. On the other hand, a domain object Location could contain an array of Course objects as class member, if needed. You see the difference?
Now, in your case, indeed pass a Location as argument to a Course object. And, in the Course repository, define a method like fetchCoursesWithLocations() in which you run only one sql query to fetch 50 courses TOGETHER WITH the corresponding location details - based on your criterias - into an array. Then loop through the records array. For each of the record item build a Location object and a Course object (to which you pass the Location object as argument). Then pass each so created Course object to another array holding all resulting Course objects, or to a CourseCollection object (which I recommend). In the end return the Courses array (or the CourseCollection content) from the method.
Now, all is somehow too complex to present in here. But I'll give you here three great articles (a serie) which will make the whole process very clear to you. You'll find out in there how a CourseCollection should see, too. In the articles (from the second one upwards), it is used the term "Mapper", which I'm pretty sure it's the same as your "repository". Actually, there are two abstraction layers for data access in the db: mappers and repositories. Plus the adapters.
Look to the part with the PostMapper and the CommentMapper. They are the parallels to your CourseRepository, respectively your LocationRepository. The same roles have Post and Comment models (domain objects!): as parallels to your Course and Location.
The articles are:
Building a Domain Model - An Introduction to Persistence
Agnosticism
Building a Domain Model - Integrating Data Mappers
Handling Collections of Aggregate Roots - the Repository Pattern

How does one keep track of many objects in OO design?

I'm struggling with an issue regarding basic object-oriented design that I don't really have the vocabulary to describe. I'm a first-year computer systems student, so my software development education so far is focused on the very basics.
In a large OO project, like for instance a role-playing game, you can end up with many objects whose names are not known at compile time. In a game example, you might have a database file containing details of different enemy encounters. A particular encounter might have the player face three goblin warriors and a troll berserker. These different enemies might all be instances of class Combatant, with different creation arguments specifying their powers and equipment.
However, when instantiating these objects, what names do we give them? Stated differently: I use Python, and when you instantiate an object, you need to give it an identifying name in order to refer to it later; but how can I name a thing if the variable name itself is not literally typed into my code?
next_combatant = load_from_file()
??? = Combatant(next_combatant)
In other words, what do I put in place of the ??? above?
The solution I'm currently using is to use lists (arrays), appending each new object to the list. This way each object does not strictly have a name in the sense of 'goblin_003', but I can refer to objects by using indices of the list, and I can also do other nice things like count how many enemies there are, etc.
My question, then: is this how it is handled in industry? Do programmers typically use arrays to keep all their objects organised? Or is there some clever trick that allows me to retrieve a variable name from file?
(I realise this question is poorly worded, so if anyone needs clarification, just ask.)
EDIT: Is there a name for using collections in this way?
Of course. Collections serve this purpose well enough. With many collections, you don't need to specify an identifier of a stored item. However, if you would like to, a dictionary is a way to go. I don't know much about python, but there should be some collection where you specify a key and a value for an item you want to store in it.
Just imagine that you are to create millions of warriors in one game. It would not made a sense to have warrior_999999 and warrior_1000000.
That's correct, you don't have variable names for all monsters and objects in your game or in other software where you need dynamic content. And you don't need any variable names really.
But what is correct way to store those objects depends on your needs, what you wanna do with them and what is purpose of your objects. You can use Arrays, Lists, Trees and what ever, what just makes sense in your use case.
If you need to identify specific dynamic object / monster in your game/software, add identifier variable to your object.
Identifier variable in your object can be just integer value. But you have to keep it so that you don't have two objects with same value.
Example, if you have 3 monster objects in array and monster object has int id; variable.
Monster1, id = 1
Monster2, id = 2
Monster3, id = 3... and so on.
In OpenGL, if you use picking, good identifier is RGBA value:
Monster1, id = RGBA(0, 0, 0, 1);
Monster2, id = RGBA(0, 0, 0, 2);
Monster256, id = RGBA(0, 0, 1, 0); and so on.
What is right identifier, depends again on your needs.

Designing a solution to retrieve and classify content based on given attributes

This is a design problem I am facing. Let's say I have a cars website. Cars have the following attributes with different possible values.
Color: red, green, blue
Size: small, big
Based on those attributes I want to classify between cars for young people, cars for middle aged people and cars for elder people, with the following criteria:
Cars_young: red or green
Cars_middle_age: blue and big
Cars_elder: blue and small
I'll call this criteria target
I have a table cars with columns: id, color and size.
I need to be able to:
a) when retrieving a car by id, tell its target (if it's young, middle age or elder people)
b) be able to query the database to know how many views had cars belonging to each target
Also, as a developer, I must implement it in a way that those criteria are easily changed.
Which is the best way to implement it? Is there a design pattern for it? I can explain two possible solutions I thought about but I don't really like:
1) create a new column in the database table called target, so it's easy to make both a) and b).
Drawbacks: Each time crieteria changes I have to update the column target for all cars, and also, I have to change the insertNewCar() function.
2) Implement it in the 'Cars' class.
Drawback: Each time criteria changes I have to change query in b) as well as code in 'getCarById' in a).
3) Use TRIGGERS in SQL, but I would like to avoid this solution if possible
I would like to be able have this criteria definition somewhere in the code which can be changed easily, and would also hopefully be used by 'Cars' class. I'm thinking about some singleton or global objects for 'target' which can be injected in some Cars methods.
Anyone can explain a nice solution or send documentation about some post that faces this problem, or a pattern design that solves it?
On first sight specification pattern might meet your expectations. Wikipedia gives a nice explanation how it works, small teaser bellow:
OverDueSpecification OverDue = new OverDueSpecification();
NoticeSentSpecification NoticeSent = new NoticeSentSpecification();
InCollectionSpecification InCollection = new InCollectionSpecification();
ISpecification SendToCollection = OverDue.And(NoticeSent).And(InCollection.Not());
InvoiceCollection = Service.GetInvoices();
foreach (Invoice currentInvoice in InvoiceCollection) {
if (SendToCollection.IsSatisfiedBy(currentInvoice)) {
currentInvoice.SendToCollection();
}
}
You can consider combine specification pattern with observers.
Also there are few other ideas:
extention of specification pattern on SQL generation, WHERE clauses in particular
storing criteria configuration in database
criteria versioning: storing information about version of rules used to assign to category comined with category itself