89

Defining Equality For Two Objects Equality can be arbitrarily defined for any two objects. There is no strict rule that forbids someone from defining any way they want. However, equality is often defined when it is meaningful for the domain rules of what is being implemented. It is expected to follow the equivalence relation contract: It is reflexive:...


42

It is in the context of the university assignment where the task purpose is to explore and understand operator overriding. This seems like an example assignment that has enough implied purpose to make it appear as a worthwhile exercise at the time. However, if this was a code review by me I would mark this up as a significant design flaw. The problem is ...


28

The problem The purpose of having these result classes derive from the same interface is so that the interface becomes what the consumer knows and works with. The consumer doesn't care about the specific implementing classes. However, your interface doesn't contain anything. You're using it as a marker interface. If I, as a consumer, receive an ...


25

Equality is a matter of context. Whether or not two objects are considered to be equal is as much a question of context as it is of the two objects involved. So, if in your context it makes sense to ignore city and street, then there is no problem to implement equality solely based on ZIP code and number. (As was pointed out in one of the comments, ZIP ...


22

Your confusion is probably caused by focussing on meaningless class and interface names, with no real usage scenario behind it. So better let us make a concrete example (I prefer C#, but it is not really different in other languages like Java). The IComparable interface in the .NET framework looks (simplified) like this: interface IComparable { int ...


19

Coupling ClassA relies upon the interface only, delegating this responsibility of passing the classB object elsewhere This is the idea. If you are separating ClassA from ClassB by the use of an interface ISomeInterface... ensuring (ClassA) doesn't know ClassB Then you do not want ClassA to ...


11

Behaviour is decisions being made. State is decisions being remembered. When OOP people talk about behaviour what they mean is the gooey sticky part of the code base that has to be changed every time a business rule changes. Rather than state what this is usually contrasted with is dry structural cerimonial code that exists mostly because the system or ...


10

I deeply believe in fail fast myself. In addition to promoting system integrity it helps debugging devs by getting them as close to the cause of the issue as possible so they don't have to slog through file after file trying to figure out where a bad value came from. However, file I/O is not something you should pretend you control. You don't. You're never ...


7

Let me step away from your actual File I/O example, as you have noticed by yourself, this introduces aspects to your question you did not intend to ask here. My answer to your general question is: don't take the idea "limiting constructor logic" too literal! If the constructor of an object cannot initialize the object properly, throwing an exception is the ...


6

A Tale of Abstractions There's a lot of confusion about this on the Internet, but the term is quite technical, and according to the Cook paper (referenced in the answer liked to by Greg Burghardt), it essentially boils down to this. OOP Objects (and the related static typing mechanisms, including classes, abstract classes and interface types) and ADTs ...


5

If I'm understanding correctly, you want to support some operations on the inner array, but not others. If this set of supported operations is general enough for a D2ArrayWrapper to make sense, then I would suggest using an interface. For example, let's say you want people to be able to read cells and rows from the array, but not write them: interface ...


5

This is a long but very interesting question, where you have exposed your step by step research. To summarize the problem: IService does some processing and returns an IOperationResult Different post-result actions need to be performed depending on IOperationResult Actions cannot be implemented polymorphically in IOperationResult because concrete ...


5

It seems to me that you are massively over complicating your life in this example by not using Exceptions instead of your IOperationResult interface. Simply throw a ValidationException or APIErrorException in your Service and handle with try catch as usual. Furthermore, say you did that, I would then say you should not be exposing the internals of your ...


4

There are multiple layers to the answer. On the technical level, state is simply the instance variables of an object, and behavior are the methods. Both of these can be extended to other granularity units, like a group of objects or the whole system. Should be clear from the context. On the semantic ("meaning") level, specifically for object-orientation, ...


4

I'm not sure that the visitor solves the "expression problem". But your understanding is correct: You can derive new visitors based on the abstract visitor. This allows to define new operations that will work on all visited elements. But if you add to the visited's object structure an element of a new type, you'll need to update the abstract visitor and ...


4

Wouldn't a forEach be same as if here? As far as branching goes yes. Loops have branches. If you seriously need to avoid branching (maybe because of some branch prediction optimization issue) the branchless fix is the null object pattern where you create a class that has a DoSomething() method that does nothing, quietly. Do that and the code becomes: ...


4

What do you guys think about using interfaces just for Adding a language element to a program makes it more complex. What we should strive for is the least complex program to fulfill all the requirements. Because that should be the easiest to write, to understand, modify, bugfix and generally speaking "produce and maintain". So if I can go and remove your ...


4

SOLID is object-oriented, by definition. You can't do SOLID without objects. You don't need SOLID to have "clean code," unless you're following the letter of Bob Martin's principles. Principles are just that; principles. They are not laws, mandates or decrees. Ergo, you are not required to follow them. Principles are just there to inform your software ...


3

I would not put any "setter" for Gold into IFighter, and only implement a setter for this property in the Person class, not in the Group class. The amount of Gold for a group is the total sum of all the gold of all group members, that makes sense. But when gold is assigned to a group, how it is distributed specificially to each person is specific game ...


3

An equality operator will claim that two objects are equal if and only if they should be considered equal, due to whatever considerations that you find useful. I’ll repeat that: Due to whatever considerations that you find useful. The software developer is in the driver’s seat here. Apart from being consistent with obvious requirements (a=a, a=b implies ...


3

Prefer early composition over late inheritance: The class of an object has to be known at creation, and most languages do not allow to change it later. So, if you create a transaction, it IS a Transaction (inheritance); If the object has to change afterwards, it must be via its state: the transaction may HAVE some properties/behaviors depending on the ...


2

There are a couple of fundamental ideas behind this. Object-Oriented Purity The first fundamental idea is that in Object-Oriented Programming, we program by composing systems of autonomous objects that collaborate by sending messages to each other. However, an if statement is not a message send, therefore, it is not Object-Oriented. Dynamic runtime-...


2

Although many answers were given, my opinion still isn't present. I was once taught that the equals method should only be doing an exact comparison between the objects Apart from what rules say, this definition is what people assume from their intiution when they talk about equality. Some answers say equality depends on context. They are right in a sense ...


2

You are trying to use the entity-control-boundary analysis to design an MVC architecture. Indeed, all the classes in your diagram belong to the „logical domain“, so are entities in the ECB logic, and model in the MVC. The boundary classes would be the GUI classes that interact with the user. They are indeed missing in the original diagram. But be ...


2

A. They're used to describe the API of various classes. Correct. I struggle with the correctness of the phrasing. It's not wrong, but it is essentially a confusing tautology. But they had to avoid calling it "the interface" to not give away the answer, and I'm struggling to find a better (and similarly terse) alternative. B. They're used to avoid ...


2

You are at the right place for a review of your design. But this is not a code review site, so don't expect an in-depth inspection here. Overview What strikes me first looking at the classes is that: there is no relation between the Snake and either FieldGrid or Tile: it feels hard to believe that both could be as independent as this diagram suggests, ...


2

There's an equivalence between your getSomething method and an abstract class. Both are examples of the Strategy Pattern. public abstract class SomethingGetter<R, MSGIN, MSGOUT> { abstract MSGOUT query(MSGIN in); abstract List<R> getResults(MSGOUT out); public SomeClass<R> run(MSGIN query) { //some logic here ...


1

So, may I state that an Iterator is an abstract data type? An ADT is a collection of data and a set of operations that may be performed on that data. An iterator is composed of a set of data to iterate and a set of operations for performing that iteration. Importantly, those operations do not define how the operator is performed. So an iterator - in general ...


1

As written i.e. you always need to send a reply, then the centralised approach is probably slightly neater. I can see two potential benefits: the common workflow (receive, handle, send) is all in one place; the handle methods, the main locus of variability, may be easier to test independently from the architecture. The first benefit is fairly minor given ...


1

Its unclear to me exactly what you are trying to do. I would have this: public function add(Package $p) { $this->packages[$p.name] = $p; } class Package { public $Name public $Style public $Categorized }


Only top voted, non community-wiki answers of a minimum length are eligible