Tag Info

Hot answers tagged

42

Instantiating a new object is always better, then you have 1 place to initialise the properties (the constructor) and can easily update it. Imagine you add a new property to the class, you would rather update the constructor than add a new method that also re-initialises all properties. Now, there are cases where you might want to re-use an object, one ...


34

There is nothing wrong with the design shown in the question. While one could also introduce abstract Scissor with two concrete subclasses, and maybe more overall clarity, it's also common to do it like shown (especially when the hierarchy is a result of years of incremental development, with Scissor being around for much longer than the concept of ...


23

You are thinking too logically! There is no logical contradiction because class definitions are not logical propositions. Having the Scissor base class return true does not correspond to saying that all scissors are right-handed. It just means that a scissor instance is right-handed unless the method is overridden in a subclass.


15

You don't. It's like saying that all animals are dogs, and then asking how to make cats meow instead of bark. If you were naming your classes properly, your Scissor class would rather be named RightHandedScissor; now does it make sense to inherit LeftHandedScissor from RightHandedScissor? One possible approach is to make Scissor class abstract, and ...


12

Since you are not a professional programmer, I would recommend sticking to simplicity. It will be a LOT easier for programmer to take your modularized, procedural code and make it OO later, than it will be for them to fix a badly written OO program. If you are not experienced, it is possible to create OO programs that can turn into an unholy mess which will ...


12

You should definitely prefer creating a new object in the vast majority of cases. Problems with reassigning all properties: Requires public setters on all properties, which drastically limits the level of encapsulation you can provide Knowing whether you have any additional use for the old instance means you need to know everywhere that the old instance is ...


10

The point of avoiding strings is not that they are inherently bad and should never be used. If that were the case, we'd omit them from our programming languages. What should be avoided is the use of strings to represent alternative values when the possible values are in fact a small set of predefined options, rather than any possible string. The danger that ...


9

When doing FP I tend to use more specific semantic types. For example, your method for me would become something like: read: MessageId -> Message This communicates quite a lot more than the OO(/java)-style ThingDoer.doThing() style


9

Another option is to introduce the handed-ness as a dependency with a default value of right-handed. In pseudocode here as I am not familiar with Ruby: class Scissors { Scissors(isRightHanded = true) { _isRightHanded = isRightHanded } IsRightHanded() { return _isRightHanded } } class LeftHandedScissors : Scissors { ...


8

So, what can functional programmers do to preserve the semantics of a well-named interface? Use well named functions. IMessageQuery::Read: int -> string simply becomes ReadMessageQuery: int -> string or something similar. The key thing to note is that names are only contracts in the loosest sense of the word. They only work if you and another ...


8

In the first program, you called Array.Reverse, a static method of the Array class that reverses the array in-place. In your second program, you called Enumerable.Reverse, an extension method that works on any kind of enumerable. As an array is a kind of enumerable, it does work on arrays. But it does not do in-place reversion, but instead returns a new ...


8

It allows me to inject any IWaveGenerator to the NoteGenerator dynamically. Also, I only need one NoteGenerator class, instead of SineNoteGenerator, SquareNoteGenerator, etc. That is a clear sign that you should use composition here, and not inherit from SineGenerator or SquareGenerator or (worse) both. Nethertheless, it will make sense to inherit a ...


8

Given the very generic example, it's hard to tell. If "resetting the properties" makes semantic sense in the case of the domain, it will make more sense to the consumer of your class to call MyObject.Reset(); // Sets all necessary properties to null Than MyObject = new MyClass(); I would NEVER require making the consumer of your class call ...


7

Whether or not NoteGenerator is "conceptually" an IWaveGenerator does not matter. You should only inherit from an interface if you plan on implementing that exact interface according to the Liskov Substitution Principle, i.e. with the correct semantics as well as the correct syntax. It sounds like your NoteGenerator might have syntactically the same ...


7

Either you are building domain models, or you are building relational database schemas. If you are building relational database schemas, use ids. If you are building domain models, do not use ids, always use references to objects. This should answer the entirety of your question. Now, if you were building a relational database schema, and if you wanted ...


7

This seems like one of those common "favor composition over inheritance" scenarios. A RestController serves as an endpoint for REST calls. Not something to govern Authorization. Not something to control the HttpCache. It's a violation of the Single Responsibility Principle. Instead, you should have classes (strategies if you'd prefer) to govern these two ...


7

I generally avoid having the class know how to serialize itself, for a couple of reasons. First, if you want to (de)serialize to/from a different format, you now need to pollute the model with that extra logic. If the model is accessed via an interface, then you also pollute the contract. public class Image { public void toJPG(String filePath) { ... } ...


6

In both of your code snippets, the use of AbstractList is discouraged.1 The correct usage is to put the new instance of list in a List variable. The abstract classes AbstractList and AbstractSequentialList are provided for the convenience of implementers (i.e. library writers) of list-like containers, by providing default implementations(*) for some of the ...


5

All three are wrong, because you are storing connection strings in source code. Source code is not the right place for configuration, because you are not expected to have to change your code (and so, do all the regression testing) every time your database moves or every time you move from development database to staging and to production database. Instead: ...


5

The way you're showing it now ("I instantiate the BallEntity this way"), it is being done by the implementation (code) that calls the constructor to create BallEntity. To be clear, the point is that the way you're showing it, everywhere that you create a BallEntity (whether in separate classes or multiple places within the same class), you're re-specifying ...


5

As Telastyn says, comparing the static definitions of functions: public string Read(int id) { /*...*/ } to let read (id:int) = //... You haven't really lost anything going from OOP to FP. However, this is only part of the story, because functions and interfaces aren't only referred to in their static definitions. They're also passed around. So let's ...


5

As Harrison Paine and Brandin suggest, I would re-use the same object and factorize the initialization of the properties in a Reset method: public class MyClass { public MyClass() { this.Reset() } public void Reset() { this.Prop1 = whatever this.Prop2 = you name it this.Prop3 = oh yeah } public object Prop1 { get; ...


5

To be clear, none of "refactoring", "abstraction" or "encapsulation" are design patterns. Neither is what you posted. As you say, it is a refactoring. Specifically, it is the one that Martin Fowler named Extract Method. The definition is "Turn the fragment into a method whose name explains the purpose of the method.", which is precisely what you are doing. ...


4

2- There's no need for NoteGenerator to expose the lower-level interface defined by IWaveGenerator. Sounds like NoteGenerator is not a WaveGenerator, so therefore should not implement the interface. Composition is the correct choice.


4

Summary: The design without the abstract class will be only be acceptable if it is carefully documented to distinguish its abstract and concrete behaviours. The Liskov Substitution Principle is generally regarded as a "good thing". By the LSP, I mean that if type S is a subtype of type T, then objects of type S should behave as objects of type T are ...


4

You are over-using SRP. Let's take a look at mappingConcern's creation-and-initialization version: public function mappingConcern($data) { $parameters = $data; $product = new Product($parameters); return $product; } $parameters is the same as $data, and $product is returned immediately, so it can be translated to: public function ...


3

Naming things should always be done in the context of their scope, and as a rule of thumb compare it to how you would refer to these things in natural language. When you want to talk about the person who owns the car, you refer to them as "the car's owner", not a "the car's person" - so that's how you should name the field - owner(actually - it's better to ...


3

Thing is, I won't be able to avoid strings completely, because as I said the user will select notes identified by their names. So what would be the best option you can think of? Is this going to be a command line program? If so, it's of course impossible to avoid dealing with string since that's what the user is typing in. I'd give the Note class a ...


3

"All scissors are right-handed"? Where do you get that idea from? Your code only expresses "scissors are right-handed by default". It's a default value, not a design decision. If there were no way of having a different value, what's the point in programming a boolean accessor function?


3

Why create a whole other classes to handle those responsibilities? Because when you're doing Object Oriented Programming, your focus should be on the objects. They are your unit of work for making the design and providing abstraction. And most importantly, they are your unit of reuse. By letting them change for different reasons, you're forcing people ...



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