Hot answers tagged

44

Thinking that we have to start somewhere, I took it upon myself to refactor a data holder class This is where it went wrong - you made a major architectural change to the codebase such that it became very different to what was expected. You surprised your colleagues. Surprise is only good if it involves a party, the principle of least surprise is ...


24

One way in which you can stick to the principle of least astonishment is to consider other principles such as ISP and SRP, or even DRY. In the specific example you've given, the suggestion seems to be that there's a certain dependency of ordering for manipulating the file; but your API controls both the file access and the data format, which smells a bit ...


21

As luck would have it, a team mate of mine was working on another module and happened to need the setters, because the values he required became available at different points in the flow. As described, I don't see what makes the code require setters. I probably don't know enough about the use-case, but why not wait until all the parameters are known ...


21

The single responsibility principle can be tricky to understand. What I've found useful is to think of it like how you write sentences. You don't try to cram a lot of ideas into a single sentence. Each sentence should state one idea clearly and defer the details. For example, if you wanted to define a car, you would say: A road vehicle, typically with ...


17

How can I promote the use of the Builder pattern in my team? You don't. If your constructor has 3 lines of parameters, it is too big and too complex. No design pattern will fix that. If you have a class whose data comes available at different times, it should be two different objects, or your consumer should aggregate the components and then ...


16

You seem more focused on being right than on working well with others. Worse yet, you recognize that what you're doing is a power struggle and yet fail to think through how things are likely to feel to the people whose experience and authority you are challenging. Reverse that. Focus on working with others. Frame your thoughts as suggestions and ideas. ...


16

This metaphor almost certainly refers to the practice of establishing the first conditional check in a while loop. If you don't do this, the loop won't work. It is a well-established pattern, and it hasn't changed since the while loop was invented. The requirement for setting the initial condition in a while loop is not a defect. int i = 0; // prime the ...


12

This is not only about POLA, but also about preventing invalid state as a possible source of bugs. Let's see how we can provide some constraints to your example without providing a concrete implementation: First step: Don't allow anything to be called, before a file was opened. CreateDataFileInterface + OpenFile(filename : string) : DataFileInterface ...


11

Is there another argument for using Builders instead of the "old way"? "When you have a new hammer, everything will look like a nail." - this is what I thought when I read your question. If I was your coleague, I would ask you "why not initialize whole object in the constructor?" That is what it is it's functionality after all. Why use the builder (or ...


8

In your example above there is actually no violation of the LSP. Each NpcParty object is still a valid Party object and can be used for it in exchange. The LSP is not about exchanging class A by class B, it is about exchanging objects of type A by objects of type B. Thus, constructors, and constraints which are only checked in there, are not subject to the ...


7

I been in the situation where I was recruited for my skills. When I got to view the code, well .. it was more then horrible. When then trying to clean it up, someone that has been there longer always suppress the changes, because they don't see the benefits. It sounds like something you are describing. It ended with me quitting that position and I can now ...


7

You are one person working on internal software and don't follow any specific formal process yet. There isn't really a name for that other than "programming", in my view. If you want to work more professionally (because stakeholders want to know when things are done, for instance), the first things that should be in place are: Source control. Use it for ...


6

Update (recap) Since I've written a rather verbose answer, here's what it all boils down to: Namespaces are good, use them whenever it makes sense Using inGameIO and playerIO classes would likely constitute a breach of the SRP. It likely means you're coupling the way you handle IO with the application logic. Have a couple of generic IO classes, that are ...


5

There are several variants of the MVP around since its original design in 1996 by Mike Potel. Martin Fowler discusses some of them in another article on GUI architecture. One of the key differences between the variants is whether the view is totally isolated from the model or not: In the first case, the presenter is the man in the middle of a "passive ...


4

As long as you want only a PDF version of your report, it's enough to simply apply good factoring practices. Write utility functions, extract common code into subroutines, choose good method names, and after a while you'll have a pretty decent maintainable report generator. However, the second it looks as if you'll have to support any other output format ...


4

There are two parts to this problem. One: the unknown list of possible categories. Two: interprocess communication between the workers to prevent two jobs of the same category being processed simultaiously. If you had a known list of categories you can have one queue and one worker per category. With unknown categories, you can still have a queue per ...


2

From the docs for sync.WaitGroup: A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.


2

While all the other answers are very useful (more useful than mine is going to be), there is a property of builders you haven't mentioned yet: by turning the creation of an object into a process, you can enforce complex logical constraints. You can mandate for example that certain fields are set together, or in a specific order. You can even return a ...


2

I'd say that the best way to go is to keep them in separate classes. Small classes are not bad, in fact most of the time they're a good idea. Regarding your specific case I think that having the separated can help you change the logic of any of those specific handlers without affecting the others and, if necessary, it would be easier for you to add new ...


2

Lets to do an exercice of creativity A's API Rest as webservice: In order to feed B and unbind B from A's data model , we need an interface that will act like a contract. This contract is going to be our webservice data model. B as standalone app: Lets wrap B into a standalone app that could be executed anywhere. Desktop or web doesn't matter. Lets say ...


2

This sounds like a use-case for event-sourcing. (The following is a bit simplified view) Event Sourcing works by storing "events", instead of data, and then constructing the actual data bij re-running the events all the time. An event log could be like: teacher A created student "Bobby Tables" teacher A assigned student "Bobby Tables" to class Maths ...


2

The simplest interface should be provided that covers all cases that result in valid state upon construction of your object. You should also be liberal in what you accept. Providing one constructor is always simpler than providing two, and writers of code that use this class won't be burdened with an extra decision. If _bar is exposed in any way from the ...


2

It sounds like this class is actually more than one class, put together in the same file/class definition. If it's a DTO, then it should be possible to instantiate it in one go and for it to be immutable. If you don't use all of it's fields/properties in any one transaction, then it's almost certainly breaking the Single Responsibility principle. It might be ...


2

Have an abstract base class and two concrete derived classes. You didn't tell us what is different, but only said "their implementations are almost the same with each other". Let's assume the database name is the only difference: abstract class Model_base { public function insert($tableName, $columns, $preds = null) { $db = $this->getDB(); ...


2

Use the factory-pattern. A factory is an object which creates objects. So when you have a weapon which shoot projectiles, pass a ProjectileFactory to it and leave the creation of the projectile to that class. You can then have different classes which extend ProjectileFactory, like BulletProjectileFactory, ExplosiveProjectileFactory, ...


2

Whilst it's admirable to check your preconditions, I wonder: is your class usage such that you'll need to check all these ? e.g. I will check preconditions for a set of components that are exposed for more general usage, but for more limited usage in which I know how the component will be used, I won't perform so many checks. The counter argument to this ...


2

From your questions, I think you misunderstand bounded context. You may want to reread Chapter 14 of the blue book. Trying to answer generally - you have to be careful about sharing concepts between two different bounded contexts. After all, part of the reason that the boundary exists is that the ubiquitous language changes. To assume that the same data ...


2

If your different bounded contexts understand the meaning/purpose of a country differently, then you need to model it appropriately different in each one. However, if we are speaking simply of reference data of ISO codes and names, then I believe it's pretty fair and standard to stash it wherever is convenient and make it accessible to all interested ...


2

Please ignore "patterns" and "anti-patterns" for now. Implement whatever you need according to your requirements. In particular, if you have a need to instantiate a boolean filter expression that acts on StudentDetails at runtime (i.e. the composition of the rules aren't hard-coded) and then to use the filtered records somehow, then your approach is ...


1

Data Transfer Objects (DTO's) have one purpose, and one purpose only: to retrieve data from a database and work with it in an object-oriented form. There's no such thing as an "anemic BLL object." It's either a first-class BLL object, or it's a DTO. It's seldom both. There are reasons why you have things like ViewModel objects. A View Model object ...



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