OOP Best Practices When One Object Needs to Modify Another - c

(this is a C-like environment) Say I have two instance objects, a car and a bodyShop. The car has a color iVar and corresponding accesors. The bodyShop has a method named "paintCar" that will take in a car object and change its color.
As far as implementation, in order to get the bodyShop to actually be able to change a car object's color, I see two ways to go about it.
Use the "&" operator to pass in a pointer to the car. Then the bodyShop can either tell the car to perform some method that it has to change color, or it can use the car's accessors directly.
Pass in the car object by value, do the same sort of thing to get the color changed, then have the method return a car object with a new color. Then assign the original car object to the new car object.
Option 1 seems more straightforward to me, but I'm wondering if it is in-line with OOP best practices. In general for "maximum OOP", is the "&" operator good or bad? Or, maybe I'm completely missing a better option that would make this super OOPer. Please advise :)

Option 1 is prefered:
The bodyShop can either tell the car
to perform some method that it has to
change color, or it can use the car's
accessors directly.
Even better still...create an IPaintable interface. Have Car implement IPaintable. Have BodyShop depend on IPaintable instead of Car. The benefits of this are:
Now BodyShop can paint anything that implements IPaintable (Cars, Boats, Planes, Scooters)
BodyShop is no longer tightly coupled to Car.
BodyShop has a more testable design.

I would assume that the responsibility of the bodyShop is to modify car objects, so #1 seems like the right way to go to me. I've never used a language where the "&" operator is necessary. Normally, my bodyShop object would call car.setColor(newColor) and that would be that. This way you don't have to worry about the rest of the original car's attributes, including persistence issues - you just leave them alone.

Since you're interested in the best OOP practice, you should ignore the performance hit you get with option 2. The only things you should be interested in is do either option unnecessarily increase coupling between the two classes, is encapsulation violated and is identity preserved.
Given this, option 2 is less desirable since you can't determine which other objects are holding references to the original car or worse, contain the car. In short you violate the identity constraint since two objects in the system may have different ideas of the state of the car. You run the risk of making the overall system inconsistent.
Of-course your particular environment may avoid this but it certainly would be best practice to avoid it.
Last point, does your bodyShop object have state; behaviour and identity? I realise that you have explained only the minimum necessary but possibly the bodyShop isn't really an object.
Functional v OO approaches
As an interesting aside, option 2 would close to the approach in a functional programming environment - since state changes are not allowed, your only approach would be to create a new car if it's colour changed. That's not quite what you're suggesting but it's close.
That may sound like complete overkill but it does have some interesting implications for proving the correctness of the code and parallelism.

Option 1 wins for me. The & operator is implicit in many OO languages (like Java, Python etc). You don't use "passing by value" in that languages often - only primitive types are passed in that way.
Option 2 comes with multiple problems: You might have a collection of cars, and some function unaware of it might send a car to bodyShop for painting, receive new car in return and don't update your collection of cars. See? And from more ideologic point of view - you don't create new object each time you want to modify it in real world - why should you do so in virtual one? This will lead to confusion, because it's just counterintuitive. :-)

I am not sure what this "C-like environment" mean. In C, you need this:
int paintCar(const bodyShop_t *bs, car_t *car);
where you modify the contents pointed by car. For big struct in C, you should always pass the pointer, rather than the value to a function. So, use solution 1 (if by "&" you mean the C operator).

I too agree with the first 1. I can't say it's best practice because i'm never really sure what best practice is in other peoples minds... I can tell you that best practice in my mind is the most simple method that works for the job. I've also seen this aproach taken in the hunspell win api and other c-ish api's that i've had to use. So yea i agree with scott.
http://hunspell.sourceforge.net/
//just in-case your interested in looking at other peoples code

It depends on whether the body shop's method can fail and leave the car in an indeterminate state. In that case, you're better off operating on a copy of the car, or a copy of all relevant attributes of the car. Then, only when the operation succeeds, you copy those values to the car. So you end up assigning the new car to the old car within the body shop method. Doing this correctly is necessary for exception safety in C++, and can get nasty.
It's also possible and sometimes desirable to use the other pattern - returning a new object on modification. This is useful for interactive systems which require Undo/Redo, backtracking search, and for anything involving modelling how a system of objects evolves over time.

In addition to other optinions, option 1 lets paintCar method return a completion code that indicates if the car has changed the color successfully or there were problems with it

Related

Ruby: Hash, Arrays and Objects for storage information

I am learning Ruby, reading few books, tutorials, foruns and so one... so, I am brand new to this.
I am trying to develop a stock system so I can learn doing.
My questions are the following:
I created the following to store transactions: (just few parts of the code)
transactions.push type: "BUY", date: Date.strptime(date.to_s, '%d/%m/%Y'), quantity: quantity, price: price.to_money(:BRL), fees: fees.to_money(:BRL)
And one colleague here suggested to create a Transaction class to store this.
So, for the next storage information that I had, I did:
#dividends_from_stock << DividendsFromStock.new(row["Approved"], row["Value"], row["Type"], row["Last Day With"], row["Payment Day"])
Now, FIRST question: which way is better? Hash in Array or Object in Array? And why?
This #dividends_from_stock is returned by the method 'dividends'.
I want to find all the dividends that were paid above a specific date:
puts ciel3.dividends.find_all {|dividend| Date.parse(dividend.last_day_with) > Date.parse('12/05/2014')}
I get the following:
#<DividendsFromStock:0x2785e60>
#<DividendsFromStock:0x2785410>
#<DividendsFromStock:0x2784a68>
#<DividendsFromStock:0x27840c0>
#<DividendsFromStock:0x1ec91f8>
#<DividendsFromStock:0x2797ce0>
#<DividendsFromStock:0x2797338>
#<DividendsFromStock:0x2796990>
Ok with this I am able to spot (I think) all the objects that has date higher than the 12/05/2014. But (SECOND question) how can I get the information regarding the 'value' (or other information) stored inside the objects?
Generally it is always better to define classes. Classes have names. They will help you understand what is going on when your program gets big. You can always see the class of each variable like this: var.class. If you use hashes everywhere, you will be confused because these calls will always return Hash. But if you define classes for things, you will see your class names.
Define methods in your classes that return the information you need. If you define a method called to_s, Ruby will call it behind the scenes on the object when you print it or use it in an interpolation (puts "Some #{var} here").
You probably want a first-class model of some kind to represent the concept of a trade/transaction and a list of transactions that serves as a ledger.
I'd advise steering closer to a database for this instead of manipulating toy objects in memory. Sequel can be a pretty simple ORM if used minimally, but ActiveRecord is often a lot more beginner friendly and has fewer sharp edges.
Using naked hashes or arrays is good for prototyping and seeing if something works in principle. Beyond that it's important to give things proper classes so you can relate them properly and start to refine how these things fit together.
I'd even start with TransactionHistory being a class derived from Array where you get all that functionality for free, then can go and add on custom things as necessary.
For example, you have a pretty gnarly interface to DividendsFromStock which could be cleaned up by having that format of row be accepted to the initialize function as-is.
Don't forget to write a to_s or inspect method for any custom classes you want to be able to print or have a look at. These are usually super simple to write and come in very handy when debugging.
thank you!
I will answer my question, based on the information provided by tadman and Ilya Vassilevsky (and also B. Seven).
1- It is better to create a class, and the objects. It will help me organize my code, and debug. Localize who is who and doing what. Also seems better to use with DB.
2- I am a little bit shamed with my question after figure out the solution. It is far simpler than I was thinking. Just needed two steps:
willpay = ciel3.dividends.find_all {|dividend| Date.parse(dividend.last_day_with) > Date.parse('10/09/2015')}
willpay.each do |dividend|
puts "#{ciel3.code} has approved #{dividend.type} on #{dividend.approved} and will pay by #{dividend.payment_day} the value of #{dividend.value.format} per share, for those that had the asset on #{dividend.last_day_with}"
puts
end

STRIPS representation of monkey in the lab

I have been reviewing some material on the representation of an AI plan given the STRIPS format, and found that different people seem to formulate the same problem in different ways.
For instance, Wikipedia has an example regarding the Monkey in the lab problem. The problem states that:
A box is available that will enable the monkey to reach the bananas hanging from the ceiling if he climbs up on it. Initially, the monkey is at A, the bananas at B, and the box at C. The monkey and the box have height Low, but if the monkey climbs onto the box, he will have height High, the same as the bananas. The actions available to the monkey include Go from one place to another, Push an object from one place to another, ClimbUp onto or CLimbDown from an object, and Grasp or UnGrasp an object. Grasping the object results in holding the object if the monkey and the object are in the same place at the same height.
Here is the Wikipedia plan (please note that it is not matched exactly to this problem description, but it is the same problem. It doesn't seem to implement Ungrasp, which is not important for this discussion):
Now nowhere in this plan can I see that the bananas are located at Level(high), so the only way this could actually be divulged from the plan would be to read through the entire set of Actions and deduce from there that the Monkey must be at Level(high) to interact with the bananas, hence they must be at Level(high).
Would it be a good idea to put this information in the Initial State, and have something like:
Monkey(m) & Bananas(ba) & Box(bx) & Level(low) & Level(high) & Position(A) & Position(B) & Position(C) & At(m, A, low) & At(ba, B, high) & At(bx, C, low)
It looks quite verbose like that, but at the same time, it allows the reader to understand the scenario just through reading the Initial State. I've also been told that we should not be using constants anywhere in STRIPS, so I thought declaring the A, B, and C as Positions was a good idea.
Is it that some people do it differently (which I feel would kind of ruin the idea of having a standardized language to represent things), or is it that one of the ways I have presented isn't in the correct format? I am new to STRIPS, so it is entirely possible (and likely) that I am missing some key points.
This is not the greatest wikipedia ever. The description of STRIPS is accurate, but a little outdated.
Generally you don't need to worry about defining all the variables in the initial state because the variables are defined by the domain (the P in the quadruple in the linked article). For an intuition as to why, you have an operator for MONKEY in your initial state, but you're still introducing a free variable m that is not defined anywhere else. You end up with a chicken and egg problem if you try to do it that way, so instead the facts in the system are just propositional variables which are effectively sentinel values that mean something to the users of the system, not the system itself.
You are correct that you need to define the level for each item as part of the initial state, but the initial state of the example actually correct considering the constraints that the bananas are always high, the box is always low and the monkey is the only thing that changes level. I would probably change the example to have the At proposition take into account the object in question instead of using different proposition names for each object but that's just a style choice; the semantics are the same.
Operators in STRIPS are generally represented by 3 distinct components:
preconditions - each variable in the preconditions list must exactly match the corresponding variable in the current state (trues must be true, falses must be falses) but you ignore all other variables not explicit in the preconditions
add effects - when the action is performed, these are the effects that variables that are added to the state
delete effects - when the action is performed, these are the effects that are deleted from the state
and sometimes a 4th cost component when considering cost optimality
The post conditions listed in your example are the union of the add effects and delete effects. The advantage of separating them will come later when you get into delete relaxation abstractions.
In your proposed initial state you have propositions that contain multiple properties for the same object (e.g. At(bx, C, low)). This is typically avoided in favor of having a proposition for each property of each object in the state. Doing it this way makes you end up with a larger state, but makes for a much simpler implementation since you don't have to decompose a state variable in order to identify the value of a specific property of an object in the preconditions list.

How can I return more than one value through function in C?

I have been asked in an interview how one can return more than one value from function. I have answered saying by using pointers we can achieve(call by reference) this in C. Then he told me he is looking for some other way of returning more than one value. I said we can return a struct object but here also he didn't seem to be impressed.
I would like to know others ways to return more than one value from a function.
I have seen this questions being asked here on SO, but could not find anything C specific.
The tricky problem is that the interviewer has some solution they are particularly happy with in mind and they are likely grading you by whether you have the same clever trick as them or not.
You could just name a few ways such as you did, and still not fall upon their secret trick. And if you knew their secret trick, you could well not be impressed with it.
So in these situations, its to turn it from interview into conversation. Once you detect you're not moving towards their ego, you can avoid heading towards the intimidating "I don't know" "I give up" and instead try out the "so do you have any clever solution? Is there an in-house recipe for this at Xyz Inc?" etc.
Any glimpse at their obviously self-impressed solution and you are back on firm ground where you can talk about it and ask them if they have thought about various factors that come to mind and basically interview them.
Everyone loves a good listener, and getting them to talk about their tricks is a good way to get them to leave the interview throughly impressed with you! ;)
There are a few ways:
Return value using the return statement (as you already know)
Return via references.
Return values via the heap.
Return values via global variables.
That depends on what you consider a value. If a value is a piece of information for you, more values could be a struct of values. More values could be also passed via pointers or arrays, even a char* containing a list of (non-zero alphanumerical) values. If you consider a value to be a bit of information a single returned uint32_t may hold 32 values. You could even mess around with signals or sockets or pipes or files.
But for you do not even know the use case and the requirements it imposes on the solution, it's indeed a rather hard task to come up with the right solution (and you actually did come up with some proper solutions ...).
Return a pointer to a structure, or pack several small datatypes into one large datatype, or use global variables.
The first is probably the cleanest way to do it, the other two might have their uses in certain situations.
If we pass the address instead of the true value of the parameters.
Then whenever we refer those parameters we do it with the address.
returning a pointer to structure is the suitable answer.(Obviously, the objective of the program can decide what's the best that can be done). The interviewer might have wanted you to say 'I don't know' which would have shown your lack of confidence in the field. I think you provided good solutions, though not what he had in his mind. You could have asked him about a typical scenario where he wanted multiple values to be returned and then discuss how struct-pointer is a reasonable alternative.

Whys is it a bad idea to have an Object[] array?

I was explaining to a friend a few days ago the concept or inheritance and containers.
He has very little programming knowledge so it was really just a friendly chat.
During the conversation he came to me with a question that i just couldn't answer.
"Why cant you just have an array of the top level class, and add anything to it"
I know this is a bad idea having being told so before by someone far smarter but for the life of me i couldn't remember why.
I mean we do it all the time with inheritance.
Say we have class animal which is parent of cat and dog. If we need a container of both of these we make the array of type animal.
So lets say we didn't have that inheritance link, couldn't we just use the base object class and have everything in the one container.
No specific programming language.
Syntactically, there is no problem with this. By declaring an array of a specific type, you are giving implicit information about the contents of that array. You could well declare a contain of Object instances, but it means you lose all the type information of the original class at compile-time.
It also means that each time you get an object out of the array at runtime, the only field instances and methods you know exist are the fields/methods of Object (which arguably is a compile time problem). To use any of the fields and methods of more specific subclasses of the object, you'd have to cast.
Alternatively, to find out the specific class at runtime you'd have to use features like reflection which are overkill for the majority of cases.
When you take elements out of the container you want to have some guarantees as to what can be done with them. If all elements of the container are returned as instances of Animal (remember here that instances of Dog are also instances of Animal) then you know that they can do all the things that Animals can do (which is more things than what all Objects can do).
Maybe, we do it in programming for the same reason as in Biology? Reptiles and Whales are animals, but they are quite different.
It depends on the situation, but without context, it's definitely okay in most (if not all) object-oriented languages to have an array of a base type (that is, as long as they follow all the substitution principles) containing various instances of different derived types.
Object arrays exist in certain cases in most languages. The problem is that whenever you want to use them, you need to remember what type they were, and stay casting them or whatever.
It also makes the code very horrible to follow and even more horrible to extend, not to mention error prone.
Plant myplant = new Plant();
listOfAnimals.Add(myplant);
would work if the list is object, but you'd get a compile time error if it was Animal.

Encapsulation concept

I have problem with concept and implementation of encapsulation.
Can someone explain it to me?
Encapsulation is a moderately easy concept once you realise it (probably) comes from the same base word as capsule.
It's simply a containment of information.
Encapsulation means that a class publishes only what is needed for others to use it, and no more. This is called information hiding and it means classes can totally change their internals without having an effect on any of their users.
In other words, a dictionary class can begin life as a simple array and progress to a binary tree of words then even maybe to some database access functions, all without changing the interface to it.
In an object oriented world, objects hold both their data and the methods used to manipulate data and that is the pinnacle of encapsulation. One way this is done is to make sure each object knows which functions to call to manipulate its data, and ensure the correct ones are called.
As an example, here's a class for maintaining integer lists in my mythical, but strangely Python-like and therefore hopefully easy to understand, language:
class intlist:
private int val[10] # Slots for storing numbers.
private bool used[10] # Whether slot is used or not.
public constructor:
# Mark all slots unused.
for i in 0..9:
used[i] = false
public function add(int v) throws out-of-memory:
# Check each slot.
for i in 0..9:
# If unused, store value, mark used, return.
if not used[i]:
used[i] = true
val[i] = v
return
# No free slots, so throw exception.
throw out-of-memory
public function del(int v) throws bad-value:
# Check each slot.
for i in 0..9:
# If slot used and contains value.
if used[i] and val[i] == v:
# Mark unused and return.
used[i] = false
return
# Value not found in any used slot, throw exception.
throw bad-value
public function has(int v):
# Check each slot.
for i in 0..9:
# If slot used and contains value.
if used[i] and val[i] == v:
return true
# Value not found in any used slot.
return false
Now the only information published here are the constructor and three functions for adding, deleting, and checking for values (including what exceptions can be thrown).
Callers need know nothing about the internal data structures being used (val and used), or the properties of the functions beyond their "signatures" (the content of the "function" lines).
Because everything else is encapsulated, it can changed it at will without breaking the code that uses it.
I could, for example, do any of the following:
make the arrays longer;
store the data sorted, or in a binary tree instead of an array to make it faster.
change the used array into a count array (initialised to zero) so that many occurrences of a single number use just the one slot, increasing the quantity of numbers that can be stored where there are duplicates.
store the numbers in a database, located on a ZX-80 retro-computer located in outback Australia, and powered by methane produced from kangaroo droppings (though you may notice a latency change).
Basically, as long as the published API doesn't change, we am free to do whatever we want. In fact, we can also add things to the API without breaking other code, I just can't delete or change anything that users already rely on.
You should note that encapsulation isn't something new with object orientation. It's been around for ages, even in C by ensuring that information is hidden within a module (usually a source file or group thereof with private headers).
In fact, the stdio.h FILE* stuff is a good example of this. You don't care what's actually behind the pointer since all the functions which use it know how to do their stuff.
link text
I always explain it to people is think of yourself as an object. Other people can see your height, they can see if your smiling, but your inner thoughts, maybe the reason while your smiling, only you know.
Encapsulation is more than just defining accessor and mutator methods for a class. It is broader concept of object-oriented programming that consists in minimizing the interdependence between classes and it is typically implemented through information hiding.
The beauty of encapsulation is the power of changing things without affecting its users.
In a object-oriented programming language like Java, you achieve encapsulation by hiding details using the accessibility modifiers (public, protected, private, plus no modifier which implies package private). With these levels of accessibility you control the level of encapsulation, the less restrictive the level, the more expensive change is when it happens and the more coupled the class is with other dependent classes (i.e. user classes, subclasses).
Therefore, the goal is not to hide the data itself, but the implementation details on how this data is manipulated.
The idea is to provide a public interface through which you gain access to this data. You can later change the internal representation of the data without compromising the public interface of the class. On the contrary, by exposing the data itself, you compromise encapsulation, and therefore, the capacity of changing the way you manipulate the data without affecting its users. You create a dependency with the data itself, and not with the public interface of the class. You would be creating a perfect cocktail for trouble when "change" finally finds you.
There are several reasons why you might want to encapsulate access to your fields. Joshua Bloch in his book Effective Java, in Item 14: Minimize the accessibility of classes and members, mentions several compelling reasons, which I quote here:
You can limit the values that can be stored in a field (i.e. gender must be F or M).
You can take actions when the field is modified (trigger event, validate, etc).
You can provide thread safety by synchronizing the method.
You can switch to a new data representation (i.e. calculated fields, different data type)
However, encapsulation is more than hiding fields. In Java you can hide entire classes, by this, hiding the implementation details of an entire API. Think, for example, in the method Arrays.asList(). It returns a List implementation, but you do no care which implementation, as long as it satisfies the List interface, right?. The implementation can be changed in the future without affecting the users of the method.
The Beauty of Encapsulation
Now, in my opinion, to really understand encapsulation, one must first understand abstraction.
Think, for example, in the level of abstraction in the concept of a car. A car is complex in its internal implementation. They have several subsystem, like a transmission system, a break system, a fuel system, etc.
However, we have simplified its abstraction, and we interact with all cars in the world through the public interface of their abstraction. We know that all cars have a steering wheel through which we control direction, they have a pedal that when you press it you accelerate the car and control speed, and another one that when you press it you make it stop, and you have a gear stick that let you control if you go forward or backwards. These features constitute the public interface of the car abstraction. In the morning you can drive a sedan and then get out of it and drive an SUV in the afternoon as if it was the same thing.
However, few of us know the details of how all these features are implemented under the hood. Think of the time when cars did not have a hydraulics directional system. One day, the car manufactures invented it, and they decide it to put it in cars from there on. Still, this did not change the way in which users where interacting with them. At most, users experienced an improvement in the use of the directional system. A change like this was possible because the internal implementation of a car is encapsulated. Changes can be safely done without affecting its public interface.
Now, think that car manufactures decided to put the fuel cap below the car, and not in one of its sides. You go and buy one of these new cars, and when you run out of gas you go to the gas station, and you do not find the fuel cap. Suddenly you realize is below the car, but you cannot reach it with the gas pump hose. Now, we have broken the public interface contract, and therefore, the entire world breaks, it falls apart because things are not working the way it was expected. A change like this would cost millions. We would need to change all gas pumps in the world. When we break encapsulation we have to pay a price.
So, as you can see, the goal of encapsulation is to minimize interdependence and facilitate change. You maximize encapsulation by minimizing the exposure of implementation details. The state of a class should only be accessed through its public interface.
I really recommend you to read a paper by Alan Snyder called Encapsulation and Inheritance in Object-Oriented programming Languages. This link points to the original paper on ACM, but I am pretty sure you will be able to find a PDF copy through Google.
Encapsulation - wrapping of data in single unit. also we can say hiding the information of essential details.
example
You have a mobile phone.... there it some interface which helps u to interact with cell phone and u can uses the services of mobile phone. But the actually working in cell phone is hide. u don't know how it works internally.
hide/bind something : eg: a capsule (which we consume when v r ill)hide/bind some powder form in itself,, means that capsule encapsulate the powder contained it.
Binding of data and behavior i.e functionality of an object in a secured and controlled manner.
or the best example of encapsulation is a CLASS because a class hides class variables/functions from outside d class..
Encapsulation:
Wrapping up data member and method together into a single unit (i.e. Class) is called Encapsulation.
Eg: we can consider a capsule. Encapsulation means hiding the internal details of an object, i.e. how an object does something. Here capsule is a single Unit contain many things. But we cant see what is there in side capsule.
This is the technique used to protect information about an object from other objects. Like variable we can set as private and property as Public. When we access the property then we validate and set it.
We can go through some other examples. Our Laptop. We can use Laptop but what operations are happening inside that we are not knowing. But we can use that. Same like mobile, TV etc.
We can conclude that a group of related properties, methods, and other members are treated as a single unit or object.An encapsulated object is often called an abstract data type.
There are several other ways that an encapsulation can be used, as an example we can take the usage of an interface. The interface can be used to hide the information of an implemented class.
//Declare as Private
private string _LegName;
// Property Set as public
public string LegName
{
get
{
return _LegName;
}
set
{
_LegName=value;
}
public class LegMain
{
public static int Main(string[] args)
{
Leg L= new Leg();
d.LegName="Right Leg";
Console.WriteLine("The Legis :{0}",d.LegName);return 0;
}
}
Note: Encapsulation provides a way to protect data from accidental corruption.
Thank you
Encapsulation means hiding the data. In other words a class only exposes those properties or information which is authorized to be seen. Consider the below exapmle where a certain property called ConfidentialMessage is accesible only to the Admin role. This property is made private and is returned through another method which checks the role of an user and return the message only for admin.
public class Message
{
public Message()
{
ConfidentialMessage = "I am Nemo";
}
private string ConfidentialMessage { get; set; }
public string GetMessage(string name)
{
string message = string.Empty;
if (name == "Admin")
{
message = this.ConfidentialMessage;
}
return message;
}
}
Putting definition of encapsulate
enclose in a capsule, from en- "make, put in" + capsule + -ate .
now capsule meaning is box, case
In real life example if you put things on desk open then it is accessible to anyone but if you put in case then it is accessible with the key of case to open.
Same way in class if you create a variable then it accessible whenever you create object of that class.But if you create function to access the variable then you have created case and function is key to access the variable.
So in programming language we are creating wrapper of the data by using getter and setter and making it private variable.
Encapsulation is a capsule, consider it to be a class enclosing or hiding fields, properties and functions.
Please check below url encapsulation is simplified with simple programming example.
http://itsforlavanya.blogspot.com/2020/08/encapsulation.html?m=1

Resources