Tag Info

Hot answers tagged

60

I would say you're taking SRP far too seriously. If your code is tidy enough that logging is the only "violation" of SRP then you are doing better than 99% of all other programmers, and you should pat yourself on the back. The point of SRP is to avoid horrific spaghetti code where code that does different things is all mixed up together. Mixing logging with ...


21

When used properly, enums are far more readable and robust than the "magic numbers" they replace. I don't normally see them making code more brittle. For instance: setColor() doesn't have to waste time checking if value is a valid color value or not. The compiler has already done that. You can write setColor(Color::Red) instead of setColor(0). I believe ...


19

You haven't said whether the filters take any parameters. For example, filter_A might be a category filter, so that it's not just a question of "do I need to apply filter_A", it could be "I need to apply filter_A and return all records in with the category field = fooCategory". The simplest way to implement exactly what you've described (but make sure to ...


15

Interfaces don't describe behaviour. Quite the opposite, sometimes. Interfaces describe contracts, such as "if I am to offer this object to any method that accepts an ISummarizableEntity, this object must be an entity that is able to summarize itself" -- in your case, that is defined as being able to return a string ID and a string Description. That's a ...


15

Any change to the ColorChoice enum affects all IWindowColor subclasses. No it doesn't. There are two cases: implementers will either store, return and forward enum values, never operating on them, in which case they are unaffected by changes in the enum, or operate on individual enum values, in which case any change in the enum must of course, ...


14

No, it is not a violation of SRP. The messages you send to the log should change for the same reasons as the surrounding code. What IS a violation of SRP is using a specific library for logging directly in the code. If you decide to change the way of logging, SRP states that it should not impact your business code. Some kind of abstract Logger should be ...


14

Enums do not create brittle interfaces. Misuse of enums does. What are enums for? Enums are designed to be used as sets of meaningfully named constants. They are to be used when: You know that no values will be removed. (And) You know it is highly unlikely that a new value will be needed. (Or) You accept that a new value will be needed, but rarely enough ...


14

It's consistency, or also "principle of least astonishment". However, your less formal definition seems fine too, more pragmatic.


10

If you design a system where 20-30 people all have to edit the same class of your codebase on a daily basis, I would say you will have a pretty big organizational issue and a pretty big architectural issue as well with your system. If such a class is a facade or something else is irrelevant. To solve these issues, I would start with splitting the teams to ...


9

Because there's no obvious way to complete the tail. Any choice on how to do it would result in a non-obvious tail. The trick is to explicitly lengthen your shortest list to match the length of the longest with values you expect. If zip did that for you, you couldn't know what values it was filling in intuitively. Did it cycle the list? Did it repeat a ...


8

I always use code first and would never think about data first unless I have to integrate with an existing database. Why? Instead of starting by figuring out what database looks like, I start by figuring out what my application does. I don't have to reconcile my up-front database design with the functionality, web pages, API's etc. Instead, I do all of the ...


8

Dependency management is a big problem in OOP for the following two reasons: The tight coupling of data and code. Ubiquitous use of side effects. Most OO programmers consider the tight coupling of data and code to be wholly beneficial, but it comes with a cost. Managing the flow of data through the layers is an unavoidable part of programming in any ...


8

However, everyone who read it, read it like 20 years ago from what it seems. Actually, it was the basis of MIT's 6.001 introduction to programming until fairly recently, and still is used for similar courses in other universities even today. Has it been superseded by another influential book I should be aware of? Not really. There are other books ...


7

As logging is often considered a cross-cutting concern I'd suggest using AOP for separating logging from implementation. Depending on the language you'd use an interceptor or some AOP framework (e.g. AspectJ in Java) to perform this. The question is if this is actually worth the hassle. Note that this separation will increase the complexity of your ...


7

I would go with the anemic domain model here. Consider the example of your ItemImageFinder. Consider a few scenarios: You decide to extend your system to also include Image thumbnails, or including alternate images. Now you need to modify your Item behavior. Clearly this is not the only reason for Item to change, so you are violating SRP. You either have ...


6

One often missed detail of the Single Responsibility Principle is that the "reasons for change" are grouped by use-case actors (you can see a full explanation here). So, in your example, the calculatePay method will need to be changed whenever new types of Employees are required. Since one type of employee may have nothing to do with another, it would be a ...


6

It's almost always what you want, and when it isn't, you can do the fill yourself. The main issue is with lazy semantics you don't know the length when you first start the zip, so you can't just throw an exception at the start. You would need to first return all the common elements, then throw an exception, which wouldn't be very useful. It's also a style ...


6

Stop thinking in terms of specific patterns. At least stop looking for places to apply patterns. Start thinking in terms of separation of concerns, and if that leads you back to a pattern, so be it. You have two different groups of concerns there. The communication interfaces (Http, Soap, etc) and the data interfaces (Import, Export, Update, etc). Your goal ...


5

is Functional Programming a viable alternative to dependency injection patterns? This strikes me as an odd question. Functional Programming approaches are largely tangential to dependency injection. Sure, having immutable state can push you to not "cheat" by having side effects or using the class state as an implicit contract between functions. It ...


5

This sounds fine. You're describing a fairly standard logging decorator. You have: component L (logging component of the system) This has one responsibility: logging information that is passed to it. component A implements I This has one responsibility: providing an implementation of interface I (assuming I is properly SRP-compliant, that is). ...


5

The composite pattern is a good choice for (recursive) tree-like structures, where the clients want to use operations from the interface without actually knowing if something is a composite or a leaf. In other words, they are expecting the derived classes to confirm to the Liskov substitution principle. What does not matter is how the operations are ...


5

The concept you are looking for is known as "Hysteresis" (Wikipedia). But don't waste too much time reading the article, as your situation is rather simple. You have a number of inputs, which have states, and you also have a "logical state" (person in or out of home) which you need to compute out of them. The "logical state" cannot simply be a direct ...


4

You have chosen the better path for this design because you are defining a specific type of behavior that will be required of multiple, different, types of objects. Inheritance in this case would imply a common relationship between the classes that does not actually exist. In this case, composability is favored over inheritance.


4

Where we should put search action? In GET /search/:text. This will return a JSON array containing the matches, every match containing the album it belongs to. This makes sense, because the client may be interested not in the track itself, but the entire album (imagine that you are searching for a song which, you believe, was in the same album as the one ...


4

No, they're not. The purpose of auditing is to determine who did what in the past. The current data is irrelevant for this purpose, but you will need to record which data changed - there's no point in saying "user Dave change the person table" without saying what he changed. This information doesn't have to be recorded so formally though. You might like to ...


4

I sounds like you're trying to create an adapter around a third party library to avoid it becoming coupled in your business logic. Out of the two approaches you mention, the first one seems the best idea, as it's the most flexible and you can separate your business logic from the adapter (i.e. the adapter will basically be a pass through to the third party ...


4

Enums are a great improvement over magic identification numbers for closed sets of values that do not have a lot of functionality associated with them. Usually you don't care about what number is actually associated with the enum; in this case it is easy to extend by adding new entries at the end, no brittleness should result. The problem is when you have ...


4

You can use a variable with 3 possible states: someone at home nobody at home indeterminate These states are mutually exclusive, so it will make sense to use them for modeling. Whenever the door gets opened, set the state to "indeterminate". Whenever the door gets closed, start a timer, and when the timer ends, you change the state to "someone at home" ...


4

Decorators usually augment the original functionality in some way, not replace it altogether. So they need to hold a reference to the original object. For example, a decorator that adds memoization to a function will need to be able to call the original function if its result is not found in the cache. However, the calling code should not need to know if ...


3

So just going purely on the limited information in your description, the common base class seems like an appropriate place to put common processing logic.



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