New answers tagged

0

If you want to stick to OOP, there are multiple issues with your current approach. Although, actually shipping a game is a much higher priority that in other industries, so whatever floats your boat. All the nice programming patterns usually have trade-offs, it's up to you to decide if they are worth it. The main problem here is that the config is mixed ...


2

I'm not sure about the "object needs to be converted into a subclass instance" part but a subclass accepting a superclass as a constructor parameter is very common. But the object is not being "converted", it most probably copies the state of the object passed in the constructor (parameter can actually be of a type that is at the same ...


0

Is it acceptable to have a subclass constructor that takes a superclass object as an argument? There's no programmer police, so it is acceptable.  But without any details we cannot provide anything but general guidance. We model for purpose: to accomplish something — or more specifically in support of some automation scenario.  Modeling without purpose or ...


4

You may want to reconsider the use of inheritance for what you are trying to do. Converting an existing instance of an object into a new instance of its subclass is something unheard of and is not the way inheritance is supposed to be used. It defeats its purpose. It seems pointless to have B descend from A when A merely provides some input for the ...


0

Real life most of the times adapts itself to a model design as much efficient as possible. You should always keep reality into account when you design your classes, in this case if you don't have a Driver or a supervisor you should consider adding one. If you are modelling a self driving car the driving software should be abstracted from the car structure ...


0

Let’s say your car had properties width, height, maxWeight, actWeight and your road has properties maxwidth, maxheight, maxActWeight, maxActHeight. With that information it’s easy to check if the car can drive on the road (you need some other properties obviously). Now it’s up to you to put the decision into the car object, the road object, some other object,...


1

I'm guessing that you're actually not writing a racing simulation, so I'm going to disregard this talk of cars and roads. So, your question is this. You have two kinds of objects: C objects and R objects. Given a C object and an R object, how should your software determine whether or not the objects are compatible with each other? And the answer is that ...


3

Without knowing where you want to go with this or what problem is to be solved I think I can still create a world that makes sense. The first thing that comes to mind is a track. A track is made up of linkable segments. A track segment has road quality properties. So the track has a collection of segments. A track segment has a collection of cars with a ...


4

The more I think about this, the more I think it's a great question. Welcome to the art of design. Here's the thing, as other's have noted, there's no clear answer. I'll go even further and tell you that whatever you choose, you'll probably want to change something about how you went about it later. This is a tough problem in Object Oriented Design. It's ...


0

It really depends on what the purpose of the method is. Because you can't define methods outside of a class in Java, the approach you show is standard practice for utility methods i.e. things that generic and address cross-cutting concerns. You can find classes like this throughout the JDK e.g. the Collections class. However, if this is a 'behavior' ...


2

There something incomplete in this design: In Car.ride() your comment tells that the car only rides if Road is ok. But which Road? How does the Car know about the Road? Is Road.startRace() really a responsibility of the Road? And how is the Road informed of the Car to consider in its cars collection? Hence, a first important question for your design is: ...


-2

having arrays of pointers to functions is actually "best practice" for libraries, and is an absolutely critical and fundamental technique for modular Operating System design. places where the technique is used: Python, (cpython) Apache Portable Runtime Util (fundamental basis of apache2) inside the code generated by c++ compilers for virtual ...


3

No, you shouldn't. If the "type" has a behavior, then you should make it a proper object. This will make it its own smaller, cohesive thing. It becomes slightly easier to maintain, because it is not mixed with other stuff, and also properly named. Also, by making it its own type, you (and others) will not accidentally mistake any string for a "...


1

Start from the simple, complicate things when you must. Very simply put, avoid any level of complication/abstraction unless it actually solves more problems than it creates. In order to cut down on fluff, but also ensure that you don't cut corners either, it helps to err on the side of simplicity, and elaborate as you see fit. For example, first develop a ...


1

but in this way I'd have to update the whole aggregate and also the other appointments, that were not updated. This would be bad performance-wise. Yes, when doing strict DDD, the repository always saves (and loads) entire aggregates. And yes, this would result in rather bad performance with your model. Have a Doctor#schedule method, that would return just ...


5

My recommended methodology to find the "right number of classes" is the YAGNI principle, as explained in this former answer from 2019: Make a decision about the requirements you want to code in your next milestone. Don't put more requirements on the list than you expect to implement in a cycle of a few days, two weeks at maximum. Implement as ...


3

Let's say you had just one class: Player, responsible for handling everything related to the player, such as knowing how to be displayed on screen, knowing how to respond to user input, checking collision with other game objects, and so forth... Furthermore, let's say you took it to the extrem and had only one class Game, responsible for handling everything ...


4

Some coupling must exist, otherwise a program would not be able to do anything (if nothing knows about anything, no calls can be made). This kind of coupling certainly exists in your "manager" classes. The thing that's bad is coupling that makes your code hard to change, and most of it is kind of accidental. You start with certain best practices, ...


2

Looking at this method from the customer in their example: public void buyPaper(PaperBoy paperBoy) { final MonetaryAmount price = paperBoy.getPaperPrice(); if (wantsPaper(price)) { final MonetaryAmount money = wallet.takeMoney(price.getNumber()); final Optional<Paper> paper = paperBoy.sellPaper(money); ...


2

Since you're creating a Docker container every time you run a test, and destroy it once the test is finished, the code which creates and destroys the container is, I imagine, in the SetUp/TearDown methods. What you should consider is how different are those SetUp/TearDown methods from class to class. If all they do is to call a method which would create/...


0

"I would ... call dog an instance of INameable" That's fine, don't overthink it. Each instance of Pet is also an instance of INameable, that's the gist of inheritance. This kind of "replaceability" has also a name, it is called Liskov substitions principle. Perhaps dog is also simply an "implementation" of INameable No, that ...


1

First let's get the terminology right. we usually inject the dependencies by instantiating them in the constructor of the class we are injecting to This is nonsense. You either inject, in which case the dependency object pre-exists, OR you create, in which case it is not injected because it does not exist yet. The choice boils down to the scope of the ...


1

It could be that there is a problem in identifying what is aggregate root in your domain. In your case, will doctor or patient alone will be able to tell you any business story, is it that in this context maybe both of them are only relevant if there is an appointment ? If that is the case then I consider Appointment as aggregate root and all the ...


1

I have a couple of points to highlight, that might give you a different perspective, even if none of them are a simple yes/no answers. In your class "model" you highlight the data elements. This is not really relevant for an object design. Data is secondary, public behavior is what tells me what an object is. In case you're highlighting that you ...


4

It is not very sensible to ask what one does "usually" - how to design this kind of injection should depend on the requirements within the system, not on some habit of the programmer. When a certain dependency A can be created before the construction of a dependend object of type B, injecting an A-object through the constructor of B is often the ...


2

Object-oriented approaches are legitimate. Non-OOP approaches are legitimate. But mixing them like this does not seem wise. You have noticed that all CategoryB objects also have all methods of CategoryA objects. But does this mean that that CategoryB is a subclass of CategoryA? If it is a subclass, then wherever your code expects a CategoryA instance you can ...


0

One important aspect that all other answers have not touched upon is ownership. Your coin represents a resource. Ideally, the same coin cannot be spent twice in a row without having been recovered in the mean time. I think that this is what your in_vending_machine boolean attempts to model. It is indeed possible to use such a boolean, but this doesn't hold ...


1

The solution we want here is this: we need to add a method to the old classes which converts from them to the new classes. This works fine in an OOP system in which new methods can be easily introduced over existing classes. Here is one I made myself, for TXR Lisp: ;; We have some old classes (defstruct old-a () datum) (defstruct old-b () datum) ;; We ...


14

I'm not going to criticize your design because I see that it's not the point. Indeed coins shouldn't know about vending machines, and the related arguments, are valid. Let's assume that these classes are just dummies like Foo and Bar. The crux of your question seems to be in these code comments: coin->Insert(vending_machine); // which ...


0

It's difficult to say without knowing what different type of criteria could be, but this is an aproximation. Have Feature implement ConditionalFeature interface ConditionalFeatures have Criteria ConditionalFeatures have UIElements A Criterion have CriterionComponents A CriterionComponent can be inspected to find out if it meets the criteria Product ...


2

It's a technical foul, but mostly an excusable one. While this is ostensibly doing the exact thing that LSP examples tend to demonstrate, as you are building a mapper here, needing to know concrete types is one of the few cases where upcasting is actually a reasonably well-justified approach. That being said, things can be rejigged a bit here to further ...


3

Not to be too overly literal here... but "How do interactions between objects work?" has one answer: Exactly as you define them to. Other answers go into more detail and more specifically address your detailed question... definitely see those. But I think you're missing a core point, just by the way this question is asked. Don't get so lost in ...


3

Rather than playing lawyers over whether this violates the Liskov Substitution principle, let's look at what this interface could actually be used for. In the comments you give this example of using the interface in a service: class SomeService { private OldToNewConverterInterface $converter; public function __construct(OldToNewConverterInterface $...


2

In short One could defend that this design is LSP compliant thanks to the exceptions foreseen in the interface definition. However, this theoretical analysis is misleading since it is based on a useless contract that does not correspond to the expectations. In reality, there your scenario allows no subsituability with a meaningful result in general. Some ...


5

Coin should have only getters about their value and no insert method since it doesn't have any responsability other that being a legit coin. VendingMachine should have an Accept(Coin* coin) method. Hence: vending_machine->Accept(coin);


35

In your design, coins need to know about vending machines. This unnecessary coupling seems to be a wrong start: The vending machine’s responsibility is to provide a product if the price is paid. The latter is achieved by inserting coins. So the vending machine needs to know about coins and inserting coins to achieve its purpose. Moreover it probably needs ...


12

The code is being too literal in attempting to model the real world. Object oriented programming does not need to model the real world. Instead, it should model the business process of purchasing something from a vending machine. Instead of a Coin class, consider using an integral type representing the number of cents (if using USD) or another small unit of ...


2

I would argue that the vendingMachine should be responsible for setting the status of the coin. You want to minimize the risk that someone does something incorrectly like calling coin->Insert but not vending_machine->InsertCoin. Requiring sequences of calls like this to be done for correct functioning makes the system very difficult to use correctly. ...


3

As you say, both classes do the same, abstractly speaking. Perhaps it would be worth trying this: Forget about inheritance here, it would add unnecesary complexity in this specific case. The behavior is almost the same, and even if it were behavior that changed, it's better to do it by injecting it (composition) Extract interfaces from both classes (IDE ...


1

I would suggest considering ORM classes as only having responsibility for representing the shape/structure of underlying database records (from tables, but potentially also views/queries/stored procs/etc) rather than trying to include any behaviour in those classes. Database persistence and Object-Orientation seek radically different goals and therefore ...


1

It very much depends on your class, what it does, how you expect to use it, and what kind of performance optimization you're looking for. If you're looking for the constructor to trigger some external work, e.g. a cleanup of the file server, that is not appropriate. But I suspect you're thinking more along the lines of calculations of values that are ...


-1

Problems with logic in constructors: It's considered bad practice for constructors to throw exceptions Constructors are not inherited, so you cant mock or dependency inject them Calling code often doesn't control when they are called eg deserialisation or binding They are not optional, so lists of objects or copies etc are problematic However, in your case ...


Top 50 recent answers are included