23

The problem you're dealing with is called temporal coupling You're right to be concerned about how understandable this code is: private func setupNodes() { createNodes(); connectNodes(); } I can guess what's going on there but tell me if this makes what else is going on a little clearer: private func setupNodes() { self.nodes = connectNodes( ...


20

There are a couple of flaws in your Team Lead's argument: Well-designed classes and enums are intended to be used anywhere in your project, not just where they may make sense logically. Classes and enums that are properly documented with XML comments are very self-describing, by merely hovering over the item referencing it. You can always get to a class or ...


19

Large code bases aren't designed, they evolve. A lot of things that don't make sense when looking at a current snapshot, make perfect sense when you take history into account. And I don't just mean the individual history of the code base, I also mean the history of software engineering practices in general. Unit testing pretty much always existed to some ...


15

Separate the shared code off into a library, and include the library in the projects. As an Android developer, you're presumably using Java. Consider using a dependency management tool like Maven or Ivy. A side effect is that this will help maintain separation of concerns by enforcing modularity. The cost is that it may take some work to separate; the ...


13

I don't agree with either of the two proposals. Constants should be in their pertinent classes, not in an all-constant class in either of the two forms proposed. There shouldn't be constants-only classes/interfaces. A class CreditCard (not an internal class) should exist. This class/interface has methods relative to credits cards as well as the constants ...


12

There is no industry standard as such. You could look into sample Apple Source Projects to see how they do it.. You could however, try organizing your files into Groups & associate each group to a folder.. Organize all Controllers in One Group with Subgroup for each usecase. Put all views in One Group and subgroup for each usecase. Organize All Models ...


12

After quite some reading and tests, I have made a basic demo C++ project demonstrating the use of CMake, CTest + boost.test, CPack and Doxygen and using more or less the organization I mentioned in my question. The project shows how to make subproject dependencies, how to compile the whole repo or only a subproject, how to package, how to test and how to ...


11

One company I've worked for had the same problem, and the approach to tackle the problem was this: A common framework for all new projects was created; this includes all stuff that has to be the same in every project. E.g. form generating tools, export to Excel, logging. Effort was taken to make sure that this common framework is only improved (when a new ...


11

It sounds like the fundamental problem is not just code repository maintenance, but a lack of suitable architecture. What is the core/essence of the system, that will always be shared by all systems? What enhancements/deviations are required by each customer? A framework or standard library encompasses the former, while the latter would be implemented as ...


11

Version control. Git. Git Submodules. Put your projects under version control, using a dvcs like git or mercurial etc. Put the shared code in a submodule in git. Use the submodule in the projects that need it. When you update the submodule, can pull the changes to other projects with a single command.


10

it came up that the constants are too scattered and should all be organized into a single "master" constants file. This is the 100% wrong solution to the problem of constants being "hard to find". It's a fundamental error (unfortunately all too commonly perpetrated by programmers) to group things by technical criteria like being constants, enums or ...


10

Common guidance in .NET land, in most cases, is to have every class and interface in their own file. With a 1:1 correspondance between files and classes, navigation becomes easier. This argues against option #1. Regarding the choice between #2 and #3, I would argue for the former, with some caveats. I don't think you should have a folder for interfaces, ...


10

Separate functions, for two reasons: 1. Private functions are private for exactly this situation. Your init function is public, and it's interface, behavior, and return value is what you need to worry about protecting and changing. The result that you expect out of that method is going to be the same no matter what implementation you use. Since the rest ...


9

You are right. Your suggestion allows a programmer to import static Constants.BankAccount.* and eliminate countless repetitions of 'BANKACCOUNT_'. Concatenation is a poor substitute for actual scoping. That said, I don't hold out a lot of hope for you to change the team culture. They have a notion of proper practices, and aren't likely to change even if ...


9

Should I move ClientQueryBuilder class to Service namespace? No. You will end up with one giant namespace. But I think the flaw in the logic goes deeper. You say that namespaces are a way of organising your project. But I disagree. Projects are a way of organising your solution. Namespaces are a way of not duplicating class names across projects. So ...


8

GUI classes can quickly grow into a ball of mud if they're not managed carefully. Simple refactoring will do the trick. Some tips: Push everything that's not directly related to the GUI into separate classes. Refactor as much of the remaining code as possible out of the event handlers into their own methods. Use #regions to separate the event handlers ...


7

In general, when the inner function is small and you want to make it clear that it's only useful to the enclosing function. Alternatively, when you need to return a function. The latter scenario is trivial since generally the inner function relies on variables in the enclosing functions's scope, so declaring it anywhere else isn't an option. You might be ...


7

In C++ you have full flexibility how you want to organize your files. But you have to get accustomed to this freedom to make the good choices: A first practice is to have include guards in headers, in order to avoid that due to shared dependencies, the same header gets included multiple times. A second is discipline: make headers self-sufficient and ...


7

this creates an entirely new issue where there are two separate hierarchies — one for namespaces, and another for the file system. That's not an issue at all though, it's perfectly normal. Coupling the namespace and filesystem structures is (so far as I know) unique to Java. Trying to import this idiom into any other language where it isn't already ...


6

Both approaches work, and that's what's important at the end of the day. That said, your approach is common enough to be considered a pattern, or more accurately a good enough improvement over the constant interface anti-pattern. I don't see what's complicated about it, but that's a discussion you should have with your team.


6

Your options for resolving circular dependencies are: forward declaration Yes, this really is commonly used and isn't considered a hack. Note that only the public interfaces of your two interdependent types need the forward declaration: if the implementation is out-of-line, it's a separate translation unit, and there's no problem with each including the ...


6

Say I have some kind of game where there is a class representing the game world and a class to represent the units. If the game world class has a method to get the unit at a location, that's all well and good. I guess you mean something like this // Gamworld.hpp #ifndef GAMEWORLD_HPP #define GAMEWORLD_HPP #endif #include "Unit.hpp" class Gameworld { ...


6

Software patterns are mostly about vocabulary. They give software developers a language by which they can communicate high-level design concepts. But patterns are not a design methodology; if you're trying to write software by stitching together well-known software patterns, you're probably doing it wrong. What you really need is an effective ...


5

Certainly there is a limit to the complexity the human mind can grasp. You cannot expect somebody to know his way around millions of lines of code. That is why you should structure and document it in a reasonable and comprehensible way. Usually, chances to structure code are left out. You won't find a database class in the package for a graphical user ...


5

No one else mentioned the double-edged sword yet, so I'll add my 2 cents. If you have multiple projects and they all share some reusable code, according to good programming practices/principles (DRY for example), you should place the code in one global place and structure it in such a way so that it can be shared by all your projects without any ...


5

Since an interface is abstractly similar to a base class, use the same logic you would use for a base class. Classes implementing an interface are closely related to the interface. I doubt you would prefer a directory called "Base Classes"; most developers would not want that, nor a directory called "Interfaces". In c#, directories are also namespaces by ...


4

I worked for many years on a Pension Administration application which had similar issues. Pension plans are vastly different between companies, and require highly specialized knowledge for implementing calculation logic and reports and also very different data design. I can only give a brief description of part of the architecture, but maybe it will give ...


4

Try to group helper functions thematically and include the theme in the library name. A library name like "helper" may by too generic, but a name like "PathHelper", "FileIOHelper" says pretty much about what functions one can expect in that lib (personally, I prefer "...Utilities", but that's just a matter of personal taste). For example, I have lib names ...


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