1

I'm writing a structural detailing (CAD) software for concrete buildings in C#. I have defined like hundreds of static classes each with one public method and if needed some private methods. Each one of these methods in these static classes does part of the job. They are called from one God static class named Building.cs.

For example one class looks like this:

public static partial class GetMainRebars
{
    public static void GetMainRebars()
    {
    }

    // other possible variables and private methods
}

The program is running very very fast compared to other similar programs. But deep in my heart, looking at the above code I feel that something still may be wrong with this design pattern. Maybe I will encounter problems in terms of maintenance, or ...? I've taught myself programming, so I may have missed many core principles during the fast self teaching process. Can you elaborate the cons and pros of the above pattern?

And one very rookie question relevant to the pattern. Let's say I define a static variable inside such a class, will it remain in memory during the life time of the program? No disposing and whatsoever? Is it OK?

Update: When the program starts I'm loading the required variables in relevant fields and properties in the Building.cs for example listOfBeams, listOfColumns, listOfRebars, listOfConnectivities and etc. Now that these variables are in place, I used the methods in static classes to do various operations on these. Let's say I get the listOfRebars and listOfColumns in one static class and generate some variables to output. Then I get listOfRebars and listOfBeams and do some other stuff.

Update2: From what I have learned based on the answers and comments, I have come up with the below pattern. I was wondering if I'm on the right path?

I have one static class: Building.cs When I create/or load a project this class holds all the properties of the building like list of columns, beams, points, etc. All of these are stored as private fields. I can access these using the class's public methods like GetColumns or GetPoints ...

Now I also have non-static classes. They contain 2-3 public methods. and do some stuff on various parts of the building.

public static class Building
{
    private static List<Column> columns;
    private static List<Beams> beams;
    private static List<Points> points;

    public static List<Column> GetColumns() 
    {
        return Columns;
    }
}

public class ColumnsService()
{
    private List<Columns> columns;
    public GroupColumns(List<Columns> columns)
    {
        this.columns = columns;
    }

    public void Group()
    {
        // group columns
    }
}

var columns = Building.GetColumns();
var columnsService = new ColumnsService(columns);
columnsService.Group();
  • 2
    The method is void and doesn't take any params. How does it communicate with the rest of the world? – Esben Skov Pedersen Dec 19 '14 at 8:40
  • 2
    Ick!! Yup, you should be "like" concerned. You need to learn more about en.wikipedia.org/wiki/… It sounds like everything is public to everyone :-( – Mawg Dec 19 '14 at 8:46
  • 2
    With such a programming style you should rather use a procedural programming language than an object-oriented one. – Philipp Dec 19 '14 at 8:51
  • 1
    @Vahid Global variables are almost always a horrible idea. If your other classes need the data that the Building class gets, give it to them. Don't have every part of the program mutating and retrieving data that every other part of the program needs. – Doval Dec 19 '14 at 13:17
  • 1
    @gnat Since the question is about design patterns it is a better fit here. The question seems to have changed enough that it is targeting our audience more directly. I think this question is fine as is. – maple_shaft Dec 22 '14 at 13:43
7

Using static classes like this is simple and efficient. Like most things that are simple and efficient it comes with drawbacks:

  • your code will be difficult to unit test because any object that uses these static methods cannot easily be separated from them, so tests will have to include them, whereas usually we'd aim to use either stub or mock implementations of the collaborators of the object being tested.

  • it increases coupling, which has the effect of making your code hard to change.

  • it leads to needing large amounts of global state, which in itself also leads to testing being hard (global state can make tests dependent on each other, which is undesirable) and making changes harder (global state can lead to hard-to-identify interactions between apparently unrelated areas of the program)

The best approach would be to change the objects to non-static and use dependency injection to manage the dependencies between objects.

  • Thank you so much. What is dependency injection? – Vahid Dec 19 '14 at 9:02
  • Dependency injection is infrastructure for dealing with the inversion of control pattern(IOC). I'd say start with structuring your code using the IOC pattern and later dependency injection can make your life a little easier. – Esben Skov Pedersen Dec 19 '14 at 9:06
  • The case here that the classes very very much need the same variables in the Building.cs class. That's why I have defined the variables in the Building.cs as public. What other choices I have here? – Vahid Dec 19 '14 at 9:08
  • Most of those disadvantages are only an issue if you have global state or don't use higher order functions where appropriate. – CodesInChaos Dec 19 '14 at 9:30
  • @vahid it's hard to come up with specific suggestions without knowing lot more about your code, but one thing you should consider is the object-oriented design strategy of "tell, don't ask", which loosely means that instead of having a function pull information from other classes, it should instead tell objects of those classes to do something with the information themselves. Also, if your Building class really interacts with so many other classes, it is probably doing too much work. Try to break it into smaller chunks. – Jules Dec 19 '14 at 9:52
1

I am not familiar with C#, but it is my conviction that one should try to limit global values and classes as programming in general. Of course depending on the sircumstances. Always try and keep your classes to a minmum (but logical) responsibility. You should do some reading on the subject "low coupling high cohesion".

If you have a lot of classes interacting or depending on eachother, maybe you could implement a mediator design pattern or a observer pattern.

But it could sound to me that you haven't spent time doing some design of your project. We can give a better answer to your question, if you could provide us with an explanation of the domain or how the objects relates/should relate to eachoter.

  • May I ask why the variable in Building.cs is important to the rest of the classes? What is the relations? – SimonKaae Dec 19 '14 at 9:19
  • When the program starts I'm loading the required variables in relevant fields and properties in the Building.cs for example listOfBeams, listOfColumns, listOfRebars, listOfConnectivities and etc. Now that these variables are in place, I used the methods in static classes to do various operations on these. Let's say I get the listOfRebars and listOfColumns in one static class and generate some variables to output. Then I get listOfRebars and listOfBeams and do some other stuff. – Vahid Dec 19 '14 at 9:23
  • Okay, I seem to understand that the Building.cs is an entity class what should represent a "real(in theory) house"? Or is it multiple houses? – SimonKaae Dec 19 '14 at 9:27
  • Yes, exactly! It is a single house. I load the design data. Create this Building.cs, I has static properties and fields. Each of these relate to each part of a building. Columns, Beams, Floors and .... Then I use the loaded data in the Building.cs in other static classes to create other data for output. – Vahid Dec 19 '14 at 9:30
  • But now that we know it is just an entity, I will say that making it static can be okay, if your circumstance is: You program only works with only one building from the launch to termination. @Vahid consider this situation: At some point your users of your program requests that they can load in multiple buildings, so that they can eg. compare them. Your application will simply not allow this, since you can only have 1 building entity, and you will have to override the variables in the existing one to load another. – SimonKaae Dec 19 '14 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.