Becoming a software developer – episode I

Welcome to the first episode of my course “Becoming a software developer”, which is a starting point for your journey into the software development world. It also begins a first part (there will be 4 parts in total containing 4 episodes each) which is dedicated to the core concepts of object-oriented programming using the C# language.

All of the materials including videos and sample projects can be downloaded from here.


 

In case you’ve got here somehow randomly and have no clue what the heck is going, please read & watch the course introduction first.

Scope

In this very first episode, we’re talking about the following topics:

  • Q&A: .NET vs .NET Core, CLR.
  • Designing proper classes (encapsulation).

I do realize that at first I wanted to talk about other things such as:

  • Inheritance.
  • Polymorphism.
  • Interfaces.
  • Why we should strive for abstractions.

Yet it took me over 40 minutes to go through some good practices of the encapsulation therefore, all of the remaining topics mentioned above will be discussed in the second episode.

On the other hand, I do assume that you’ve gathered by now a basic knowledge of the C# language, which means that you should have an idea how to write a simple code (variables, loops, methods), declare a class, instantiate a new object etc.

Abstract

Classes are probably the most important part of the object oriented programming. They are like a blueprint of the things and entities around you. Thanks to the classes you can describe such entity using properties and allow for interaction with it via methods.
Whenever you design a class (or model actually) make sure that you make use of the available access modifiers (private, protected, public) which applies both to its properties
and the methods. Consider for example the User – most likely you would not want anyone to change it’s email e.g. to be empty or invalid. Then why would you use a public setter, instead of a private one?

And if such user must have an email, it’s probably a good idea to make a constructor that takes an email as input parameter and skip the default one with no parameters. It’s a very trivial example, but that’s the way you have to start thinking in order to model the proper classes of your application domain. Otherwise, you will run into problems – not using access modifiers correctly or at all is one of the biggest mistakes. You have to think about a real entity (e.g. the car) and what it allows you to do (public methods), what should be hidden from the car owner (private methods), what state it may have (e.g. car is running by invoking Start() method), what are the validation rules (e.g. there’s no fuel – Start() will throw an exception) and so on. All of these patterns are labeled as encapsulation.

For sure, there are use cases for classes being just a bag of public getters and setters (so called anemic classes) and that would be some special types like DTO (Data Transfer Object), ViewModels or database table mappings, but they have a specific use and are not part of the system core.

Resources

Next

In the next episode, we’ll finish our journey with classes, interfaces and abstractions in general (at its core) by talking about the following features:

  • Inheritance.
  • Polymorphism.
  • Interfaces.
  • Why we should strive for abstractions.

As usual, make sure that you’ll do your own research first about the stuff listed above.

20 Comments Becoming a software developer – episode I

  1. Pingback: Becoming a software developer – episode I – Patryk Huzarski | Personal Blog

  2. 0xmarcin

    I have a small remark, if you use DateTime class then testing

    private void Update()
    {
    UpdatedAt = DateTime.UtcNow;
    }

    may be difficult. Maybe it will be better to use some singleton wrapper that can be stubbed in unit test e.g. MyDateTime.UtcNow that provides MyDateTime.SetUtcNowForUnitTesting(…).

    Sometime people even use separate service like IDateTimeService. What do you think about this approach?

    Of course this has less importance for beginning programmers and your course is awesome 🙂

    Reply
    1. Piotr Gankiewicz

      Hi Marcin,

      Sure, you could use e.g. a simple interface that contains a Func<DateTime> property or use NodaTime etc. but it would be way too much for this example (including testing) which purpose was to show why this equality comparison inside a SetX() method may be sometimes useful :).

      Thank you!

      Reply
  3. Pingback: Dew Drop - January 26, 2017 (#2408) - Morning Dew

  4. buli

    Congratulations on making your first course! I think many of us want to record a course, but only a few really make it happen.

    While I’m not the target audience (since I already am a developer), it looks like a piece of quality work. I’d personally prefer it recorded on a smaller resolution, but I’m sure you’ll consider feedback coming from people and find out what works best 🙂

    Reply
    1. Piotr Gankiewicz

      Hi Buli,

      Thank you! Well, I think in the future episodes even the more advanced developers may find here something useful :). The problem with resolution is, that I have only 34″ available – 22″ is at my office and somehow I can’t record a screencast on my laptop directly as there are some artifacts on the screen. Therefore, the only solution for me was to increase the font size.

      Reply
    1. Piotr Gankiewicz

      Hi Lukas,
      I don’t see any point in using this keyword in that case, neither it adds any value nor increases the readability. Event the refactoring tools like R# would suggest eliminating this :).

      Reply
  5. Pingback: Becoming a software developer – episode II | Piotr Gankiewicz

  6. Raphael

    Lets suppose that we do not want to change neither a name nor a surname after an account has been created. Would it be a proper way to write it like that:

    public string LastName { get; private set; }
    //….
    public GoodUser(string email, string password, string lastName)
    {
    SetEmail(email);
    SetPassword(password);
    LastName = lastName;
    //…
    }
    One could possibly add a method – private void SetLastName(string lastName) – just to have some kind of validation, but no one could use this method from outside the class? Is that right?

    Because, as I understood, the method SetPassword allow to change the password at some time later on if wanted?

    Reply
    1. Piotr Gankiewicz

      You should only have a { get; } without the set (even private), it would make the User class truly immutable (once created, can not be changed anymore).
      The SetPassword() allows to change it later on, but for example, if you only want to assign a value during the creation of the new object and never be able to change it (even internally), you should remove the “setter”.

      Reply
  7. Dormammu

    What’s the advantage of:

    public string Email { get; private set; }
    public void SetEmail(string email)
    {
    //setter code
    }

    versus:

    private string _email;
    public string Email
    {
    get { return _email; }
    set{ //setter code }
    }

    if there’s any? Is it just a way to avoid backing field or is it considered more readable? Let’s assume that you need to create a custom getter anyway. Would you create a separate methods for both getter and setter?

    Reply
    1. Piotr Gankiewicz

      It was explained in the video. Basically, I want to explicit about assigning values to the properties. If there’s an underlying email validation that can throw an exception or another field gets also updated (e.g. UpdatedAt) etc. I personally find it “weird” to use a regular setter and for example get an exception out of nowhere. In my opinion, me the setter should be only used only for a property that can accept literally any value and has no influence on the other properties of the class.
      About the getter, I see no point of creating a custom method. I always use a getter with a proper access modifier.

      Reply
      1. Dormammu

        I understand your point but isn’t it the reason why properties were introduced – to write validation inside their setters?

        Reply
        1. Piotr Gankiewicz

          I get your point, but for me writing a complex setter is an anti-pattern. Same goes for using the ref, out keywords. Just because something was introduced, it doesn’t have to mean that it’s correct.

          Reply
    1. Piotr Gankiewicz

      This is Elementary OS, however, I tried also other distributions (really liked Antergos built on Arch Linux, but it doesn’t fully support .NET Core yet). I also have customized Ubuntu on my laptop, as the Debian distros are probably the most stable ones in terms of .NET Core support. I’ve been using a Linux for over half a year now and I really love it, the terminal is just great and I can natively use tools such as Docker, Nginx etc. Even more importantly, I have pretty much the same system, as the one that I’m using on the servers to host the .NET Core applications.

      Reply

Leave A Comment

Your email address will not be published. Required fields are marked *