OOP: Which class should own a method? [closed] - java

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I’m having trouble understanding how classes relate to their methods. Is a method something that the object does, or something that’s done to it? Or is this a different concept entirely?
Specifically, in a library’s software system, should the borrow() method belong to the class representing the library patron, or the class representing the item that the patron is borrowing? My intuition is that it should read like patron.borrow(copy), like English sentence structure, subject.verb(object); but my instructor says that’s Wrong, and I don’t understand why he would have borrow() belong to the Copy class (and he doesn’t really explain things too well). I’m not looking for justification, but can someone just explain the proper relationship?
Edit: This question was closed as “off topic”. I don’t understand. Are software design questions not appropriate for this site?

subjective :) but honestly, I'd go with the Information Expert Pattern and say something like
library.lend(item, patron)
The library contains the information about the items it has (perhaps in its catalog).
The library lends the item to the patron (which it knows because it registers them)
Not sure how your instructor sees this, but this is the level of 'abstraction' (software objects mimicking real world entities) that would make sense for your scenario.

You should not confuse the idea of OOP with one specific incarnation like Java or C++.
This limit "methods are a property of the object" is not part of the OOP idea, but just of some implementations and as you discovered it doesn't scale well.
How many methods sould an "integer number" object have? What is more logical... myfile.write(myint) or myint.write(myfile)? There is really no good general answer to this. The idea of a method being part of a single object is a special case and sometimes the bending needed to fit the problem to this solution can become noticeable or even close to a showstopper. The answer is really totally acceptable only when a method has no parameters except the object being processed: single dispatch is a perfect answer only when there is a single type involved.
In other languages you have a separation between objects and methods, so for example you have the file object, the integer object and a method write(myfile, myint) that describes what to do when the operation is needed... and this method is neither part of the file nor of the integer.

Some generic words first.
Software construction is not something which should be governed by English language rules or "beauty" or whatever, it's engineering discipline. Think of whether your design solves the problem, whether it will be maintainable, whether it will be testable, whether it will be possible to parallelize development and so on. If you want something more formalized take a look at the "On the Criteria To Be Used in Decomposing Systems into Modules" by D. L. Parnas.
As for your library example. Imagine you have a Copy outside of library, shoult it have borrow method then? How the borrowing is registered? Are you ok with either Copy or Patron classes responsible for data storage? It looks more appropriate to put borrow into a Library class. Responsibilities will be clearly divided, you wouldn't need to know much about borrowing to implement Copy and Patron and you wouldn't need much details about them to implement Library.

Public methods exposed from a class are the tasks that can be performed on the entity.
That way the class would only encapsulate its behavior.
For example:
if i say
Computer.TurnOn()
The method will only work on the computer system.
instead if i say,
SomeOne.TurnonComputer()
The someone will now have the responsibility to turn on the computer(set related properties of computer), that means we are not meeting the concept of encapsulation and scattering the class's properties all over the place.

As #Ryan Fernandes said, the lend/borrow operation cannot be with either patron or book. It has to be with some class that knows about the status of all the books and patrons of the library. For e.g., are there pending reservations against a book? How many copies are available? Has this patron paid all the fees? Is he eligible for this book? So typically this should be in Library or a LibraryService class.

The point of OOP is to create polymorphic functions that, in each implementation, deal with a defined set of data which obey specific invariants.
It follows that a method which alters an object should be defined in the class of that object. It matters less where code that is purely functional lives, but it should probably live on the type of its input (if it takes a single input) or on its output.
In your example, if borrow alters data in copy, then it should live there. If, however, you model the loan status of a book by it being held in a particular collection (either in a patron, or in a collection for the library), it would make more sense to put borrow on the holder classes. That latter design, however, runs the risk that a copy could be in more than one collection, so you would want to put some information (and a corresponding method) on the copy as well.

Not pretty sure for the exact justification , but you can think it this way, IF multiple patients go and visit a doctor, its only the doctor who know when to call in the next patient, so the next method would be a part of Doctor's Responsibility, though its tempting to think that next should be the part of Patient's responsibility as he has to go next, someways when the library book is to be issued, it should be the responsibility of book genre rather patron as book(RESOURCE) knows when it will be free .

Is a method something that the object does, or something that’s done to it? Or is this a different concept entirely?
Let me clear something about class and objects first. Class are generally used to a denote particular category. Like
Cars not Ferrari, or Porsche
Fruits not Banana, or Apple
So, it's Ferrari that is driven, and a banana that is eaten. Not their class
Its always an object that has properties and has behavior.
Even going to your case specifically.
borrow() method is an action/behavior done by a object of a person on an object of book whose records is kept by another object of the library system itself.
A good way to represent this in OO way for me would be like
libray.borrow(new book('book title'), new person('starx'));
Just for fun, What do you think about this
person starx = new person('starx');
book title1 = new book('title1');
library libraryname = new library('libraryname');
libraryname.addBook(title1);
if(starx.request(title1, libraryname)) {
starx.take(library.lend(title1, starx));
}

I guess it can go either way. There is no hard and fast rule for it. The idea is the group functions logically that makes sense. To me, Patron#borrow(BookCopy) make same sense as BookCopy#borrow(Patron). Or you may have a class LibManager.borrow(BookCopy, Patron).

Your instructor's right. Well, actually, he's wrong. I don't know.
My point is, for questions such as this, there are often no firm general answers one way or another. It largely comes down to what works best in your particular case. Go with whatever's easiest to code - it'll be the easiest to maintain. And, by "easiest to code", I suggest also taking into account the intended users of the classes (beyond just your Library, Copy and Person classes).

I was thinking about precisely that today. I came to this conclusion:
Whichever makes more sense in the appropriate context.

Related

which cannot be treated as the friend in contrast with oops

i need your help in understanding a question.
which of these cannot be treated as the friend in contrast with oop:
Function
Class
Object
Operator function
i think answer should be Operator function but i am not sure.please
anyone explain this to me.
thanks in advance.
Object.
An object is instantiated, the others are not.
Think about what 'friend' means. It's like schema, you're defining access, but it's all done at compile time... an object is a run time thing so friendship is meaningless and uninforcable. Once your code is compiled it's all reduced to pointers and references and no checks are done.
Also, to further clarify, to create friendship relationships between objects and other objects, or between objects and anything else, you couldn't do that at compile/code time, as you don't know what objects will exist and you can't reference them... Such behaviour, or similar behaviour anyway, COULD be implemented by a language, but the friendships would have to be added at run time, and this would be quite an interesting feature of a high level language, but quite a different feature to friendship as we know it.
Your question makes only sense for C++.
friend is not a contrast to OOP. friend helps OOP by allowing you to expose fewer member variables and member functions. friend allows you to expose your private members to one particular external component. Without friend, you would have to make the members public and expose them to the whole world.
Objects cannot be made friends. friend is a mechanism to control member access and hence, like public, protected and private specifiers, a compile-time issue. Objects, in contrast, exist a run-time[*].
An "operator function" (the correct word would be "overloaded operator") is not that much different from a normal function, really. You can mostly consider overloaded operators as functions with funny names. As far as friend is concerned, there is no difference whether you call your function Add or +, for example.
[*] I realise that this is a slight oversimplification when you consider template metapropgramming or constexpr.

Questions about Java code styles [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
So I have seen a lot of different coding styles, but I'm only going to talk about two big ones. I use a style where I just name everything like their class name when used in a general sense, like this:
String str = "This is some text";
But over at Java Practices, I see a style where they will put an 'I' in front of Interfaces class names, or they put 'f' or 'a' in front of object names. Take this snippet from "Don't subclass JDialog or JFrame"':
/**
Constructor.
<P>Called when adding a new {#link Movie}.
*/
MovieView(JFrame aParent) {
fEdit = Edit.ADD;
buildGui(aParent, "Add Movie");
fStandardDialog.display();
}
Why do programmers code in this style? Do a lot of people use it? And also, do professional programmers use this style?
Thanks in advance :)
This my personal opinion.
I prefer not to use prefixes on interface (or anything else for that matter). I just prefer to call it what it is. Interfaces are meant to represent an object (or part of it) without making any implication towards it's actual implementation.
Say you have a Car interface. And AudiA4 could be an implementation of that car. If you just bought a new Audi A4, you say, "I bought a new AudiA4" to those you think care about the kind of car you bought. To others, you can say "I bought a new Car". Certainly, you never say, I bought a new IAudiA4 or a new ICar.
The JFrame naming came about because it's a Swing Frame and Swing came after AWT (the original Java windowing toolkit, which already had a Frame class). Since both AWT and Swing where available at the same time, they used the 'J' prefix to demarcate the toolkits (note that JFrame extends Frame, btw). They could have called it SwingFrame but the 'J' prefix was apparently a good choice to represent the Swing package. So basically this prefix is just a naming choice, not a convention similar to the 'I' for interfance (or Impl suffix for implementations you see sometimes as well)
My point is you always have to name your classes and interface according to exactly what they represent. No more, no less. No point having a CarImpl class. Who cares that it's an implementation. Which implementation is it? Why does it need its own class? What more do I get when I use a CarImpl? What happens when I make a second implementation, I call it CarImpl2? All this is very constraining and doesn't bring much value.
Call it what it is. That's the only rule I'd set forth.
All this being said, the Eclipse project, amongst many others, does indeed use the I-for interface notation (WIKI). But it's their choice. I've seen professionals use it as well. I don't like it, but generally speaking, I respect the team's naming convention.
There is a book about such things - Code Complete by Steve McConnell
I might be wrong but the only universal convention I've seen when naming Java variables is using Camel-Case notation, that's regarding the format of the name.
As for the name itself, I've always found useful to name the variables according to what they actually are. In your String example, although you mention this would be in a general purpose variable, I would still give it a more meaningful name, like:
String message = "This is some text";
Or:
String msg = "This is some text";
Some of the Java libraries I've seen source code from tend to be quite verbose when naming variables, others just use single letter names when the variable is used in a reduced context:
public Rectangle setLocation(Point p) {
return setLocation(p.x(), p.y());
}
I think the main goal when naming variables (or anything else for that matter) is always to communicate in the best way possible the intent of what you were trying to do.
Code styles help make it easier for developers to read and understand each others code. Java conventions prescribe the use of short and descriptive identifiers, but unfortunately short and descriptive cannot always be achieved together so you may have to compromise shortness for clarity hence: atmosPres - still clear but short, atmosphericPressure - this can't be mistaken, atm - because everyone just knows ATM, right?, ap - WTF?
I first encountered the practice of prefixing variable names with a three letter type identifier while developing programs in C# - it helps the reader know what data type is contained in a variable without having to look for its declaration (due to short memory or maybe laziness?). Arrays are also prefixed with I e.g IList to distinguish them from other data types (and for what purpose, I just dunno).
For me, the worst code conventions are in C++ (if indeed there are any at all) - there's a mix of case types for data types and variables, conflicting method and function naming styles and endless cryptic abbreviation which all make it hard for non-regular C++ coders to read and understand C++ code.
What you're describing is sometimes referred to as "Hungarian notation", though it's not "Hungarian" in the truest sense of the term.
Basically, the idea is to differentiate between different classes of variables -- instance variables, local variables, parameters, et al. This serves two basic purposes:
It helps avoid name collisions, where, say, there might naturally (using "descriptive" variable naming) be an instance variable ralphsLeftFoot and a local variable ralphsLeftFoot. Using a prefix allows the two to co-exist, and, especially in languages where the local might (without warning message) "hide" the instance variable, prevents unintended changes in semantics from such collisions.
It makes the scope of variables obvious, so that, during maintenance, one does not accidentally assume that a local variable has instance scope or vice-versa.
Is this approach worthwhile? Many developers use a subset of the scheme, apparently to good effect. For instance, many Objective-C developers will name the instance variable behind a "property" with a leading "_" character, to clearly differentiate between the two and to avoid accidentally using the instance variable when the property was intended.
Likewise, many developers in a number of languages will prefix instance variables with a letter (often "m") to differentiate them from "normal" local/parameter variables.
What's probably most important is to pick a style that you (and your team) likes and stick with it. If the team likes the prefixes then use the prefixes. If the team prefers something else, stick with that. Of course, changing preferences, when a better choice is "revealed" to you, is OK, but don't switch back and forth willy-nilly.
So I have seen a lot of different coding styles, but I'm only going to
talk about two big ones. I use a style where I just name everything
like their class name when used in a general sense, like this:
String str = "This is some text";
That is awful. Imagine if someone were reading your code, trying to understand what it was doing, and they came across a variable named str. It doesn't convey any meaning to the person who has to read this code as to your intentions.
Conventions are used by and for people to improve readability, and thus the overall quality of software. Without a convention, any project that has more than one developer will suffer from varying styles that will only hurt the readability of the code. If you want to know what professionals do, look around on the internet for various conventions.

should I have logic in my model class or other classes

I just want to have other opinions about this one that I have been debating in my head, for example I have class user_controller, and class user
class User
attr_accessor :name, :username
end
class UserController
// do something about anything about users
end
The question would be should I have logic in my User class so it would be
user = User.new
user.do_something(user1)
or it should be
user_controller = UserController.new
user_controller.do_something(user1, user2)
I'm not sure which one is the best design, I personally quite like the first one so for example it would read like
john = User.new
john.accept_friend(jane)
instead of
user_controller = UserController.new
user_controller.accept_friend(john, jane)
What are pros and cons of those patterns? This is not just specific to Ruby, it's because I thing ruby is easier in typing.
Edit: There is really good conversion going on, but I quite like to here more from people. Thanks everyone.
Yes, you should keep logic in your model! That is, if you do actual object oriented programming (and it looks like you do). To quote Wikipedia:
Object-oriented programming (OOP) is a programming paradigm using
"objects" – data structures consisting of data fields and methods
together with their interactions – to design applications and computer
programs.
This is especially true if you're trying to do domain driven design (which your tags imply). DDD is all about expressing your domain with objects.
Martin Fowler says putting the logic outside your model is an anti-pattern.
Most people would say that you should not keep logic in your model-classes. Exceptions might include:
helper functions accessing a contained Collection (addToList(Object o), getFromList(int index), etc etc)
Standard Object and similar overrides (equals, hashCode, toString, clone, compareTo, etc)
Data pre/post processing (like fixing strings to uppercase or stuff like that)
Since people won't expect there to be logic in model classes, you should probably avoid it too. It will confuse other developers who might have to look at and maintain your code in the future. After all, that is why there are patterns - to help other developers recognize and maintain your code.
I believe the first one is better, you have a model and a class that has all the information needed to operate that model and that model might need some other information to do some operations.
try reading more about Information Expert.
In such scenarios, the trade off should be considered.
It is good to add accept_friend in the user class if you are sure that the user class will not grow in size going forward.
On the other hand, it is preferred to move accept_friend into service classes like UserController in following scenarios.
To avoid user class grow in size. Such logics can be moved to these subclasses(Usercontroller) thus making the classes look simple
For resuability . Tomorrow if there is a class called superuser which also needs accept_friend functionality, then UserController class can be resued like
user_controller = UserController.new
user_controller.accept_friend(Superuser1, Superuser2)

Better to extend a class or modify it directly?

So I'm working on creating a visualization for a data structure in Java. I already have the implementation of the data structure (Binary Search Tree) to start with, but I need to add some additional functionality to the included node class. As far as conventions and best practices are concerned, should I create a subclass of the node with this added functionality or should I just modify what I have and document it there?
My question is similar to what's asked here but that's a little over my head.
I know it probably doesn't matter much for what I'm doing, so I'm asking this more as a general thing.
Edit: I probably should have been more clear. My modifications don't actually change the original implementation other than to add a couple of extra fields (x and y coords plus a boolean to set whether that node is highlighted) and functions to access/modify those fields. Also the node class I'm working with is included in the BST implementation
From reading your answers it seems like there's arguments to be made for either case. I agree that creating a separate class or interface is probably the best thing to do in general. Creating another class seems like it could get tricky since you'd still need a way to extract the data out of the node. The BST implementation I'm using is generic and doesn't have any such functionality by itself in the Node class or the BST class to just return the data so at minimum I have to add that.
Thanks for the informative replies.
The question to answer is, is the 'base functionality' useful, even disirable, when you're not visualizing the data structure?
You might not even want to extend the class at all. Without more detail, it seems to me that you have a datastructure that works. You could create a NEW class that knows how to vizualise it.
That is, instead of a datastructure than knows how to visualize itself, you have a datastructure, and another class that knows how to visualize the datastructure. Heck - you may find that that evolves into another whole class hierarchy because you might need to visualize queues, stacks, etc. etc. NOTHING to do wiht your binary search tree.
Since you're asking in general, here's the short answer: it really depends on the situation.
First off, subclasses are assumed to have an "IS-A" relationship with their parent classes. If you can't say that your new subclass IS A specific kind of the original class, you're asking the wrong question, and should be making a new, unrelated class.
If the new code is closely related to the core purpose of the class, and applies to all members of the class (e.g. all BSTs), it may be better to modify. High cohesion is good.
If your new code is related to the core purpose of the class but has to do with only some objects of that type (e.g. only BSTs that are balanced), subclassing is probably the way to go.
Depending on what you're changing, how many places your code is used, how many different people/organizations are using it, &c., your changes might lead to unexpected behavior in other code, so you should think twice before modifying existing code. That doesn't mean automatically subclassing commonly used things; that would often be wrong for the reasons described above.
In your specific case, I agree with n8wrl; since visualization has nothing to do with data structures, it's probably better to implement a whole separate Visualizable interface than make a DrawableBSTNode subclass.
I would say that in the general case of adding functionality to an existing implementation, you should extend the existing implementation rather than modify it.
And here's my reasoning. If that node is used anywhere aside from the Binary Search Tree implementation, then when you modify it you'll need to find everywhere it is used to ensure that none of those places conflict with your modifications. While just adding functionality in the form of new methods generally won't cause problems, it could cause problems. You never know how an object is used.
Second, even if it is only used in the Binary Search Tree, you'll still need to make sure that the BST's implementation will play nice with your modifications.
Finally, if you do extend it, you don't have to worry about points one and two. And you get the added bonus of having your modifications kept separate from the original implementation for all time. This will make it easier to track what you have done and comment on it.
There's no simple answer, knowing when and how to add functionality is a something you have to learn over time.
Just adding to the base class seems like the easy solution, but it's polluting your base class. If this is a class you could reasonably expect another program (or even part of your program) to use does the functionality you are adding make sense in the context of your class's responsibility? If it doesn't this is probably a bad move. Are you adding dependencies linking your base class to your specific use? Because if you are that's throwing code reuse right out the window.
Inheriting is the solution a lot of engineers gravitate to, and it's a seductive route. But as I've grown as an engineer it's one that I use sparingly. Inheritance should only be used in true is-a relationships, and you need to respect behavioral subtyping
or you are going to regret it later on. And since Java only allows single inheritance it means you only get one shot at subtyping.
Composition (especially with interfaces) is often a better idea. Often what looks like a is-a relationship is really a has-a one. Or sometimes all you really need is a helper class, that has many functions that take your original class as an argument.
However with composition there is one issue, want to store these objects in your tree. The solution here is interfaces. You don't want a tree that stores Nodes. You want to objects that have an interface that can give you a node.
public interface HasNode {
public Node getNode();
}
Your node class is a HasNode with getNode just returning this. Your NodeVisualizer class is also a HasNode, and now you can store NodeVisualizers in your tree as well. Of course now you have another problem, your tree could contain NodeVisualizers and Nodes, and that wouldn't be good. Plus when you get a HasNode back from the tree functions you have to cast them to the right instance and that's ugly. You'll want to use templates for that, but that's another answer.
Mixing up logically independent functionalities will cause a mess. Subclassing is a very special relationship, often overused. Subclassing is for Is-a-Kind relationships.
If you want to visualize something, why not create a fully independent Class for that? You could simply pass your Node object to this. (Or even better, use an Interface.)

Why is using a class as a struct bad practice in Java?

We recently had a code review . One of my classes was used so that I could return/pass more than one type of data from/to methods . The only methods that the class had were getters/setters . One of the team's members ( whose opinion I respect ) said that having a class like that is bad practice ( and not very OOP ) . Why is that ?
There's an argument that classes should either be "data structures" (i.e., focus on storing data with no functionality) or "functionality oriented" (i.e., focus on performing certain actions while storing minimal state). If you follow that argument (which makes sense but isn't always easy to do) then there is nothing necessarily wrong with that.
In fact, one would argue that beans and entity beans are essentially that - data containers with getters and setters.
I have seen certain sources (e.g., the book "clean code") arguing that one should avoid methods with multiple parameters and instead pass them as a single object with getters and setters. This is also closer to the "smalltalk model" of named parameters where order does not matter.
So I think that when used appropriately, your design makes sense.
Note that there are two separate issues here.
Is a "struct-like" class sensible?
Is creating a class to return multiple values from a method sensible?
Struct-like classes
An object class should -- for the most part -- represent a class of real-world objects. A passive, struct-like java bean (all getters and setters) may represent a real-world thing.
However, most real-world things have rules, constraints, behaviors, and basic verbs in which they engage. A struct-like class is rarely a good match for a real-world thing, it's usually some technical thing. That makes it less than ideal OO design.
Multiple returns from a method
While Python has this, Java doesn't. Multiple return values isn't an OO question, per se. It's a question of working through the language limitations.
Multiple return values may mean that an object has changed state. Perhaps one method changes the state and some group of getters return the values stemming from this state change.
To be honest, it sounds fine to me. What alternative did the reviewer suggest?
Following OOP "best practices" and all is fine, but you've got to be pragmatic and actually get the job done.
Using Value Objects like this (OO speak for 'struct') is a perfectly legitimate approach in some cases.
In general, you'll want to isolate the knowledge needed to operate upon a class into the class itself. If you have a class like this, either it is used in multiple places, and thus can take on some of the functionality in both of those places, or it is in a single place, and should be an inner class. If it is used in multiple ways, but in completely different ways, such that there is no shared functionality, having it be a single class is misleading, indicating a shared functionality where there is none.
However, there are often specific reasons for where these general rules may or may not apply, so it depends on what your class was supposed to represent.
I think he might be confusing "not very OOP" for bad practice. I think he expected you to provide several methods that would each return 1 value that was needed (as you will have to use them in your new class anyway that isn't too bad).
Note that in this case you probably shouldn't use getters/setters, just make the data public. No this is "not very OOP" but is the right way to do it.
Maybe Josh Bloch offers some insight into this here.

Categories