Skip to main content

How to separate data and logic to achieve Single Responsibility Principle in C# way? [Resolved]

This question already has an answer here:

I'm still learning C# and best practices around it.

Consider this block of code

public class Counter {
    private int _value = 0;

    public void SetValue(int x) {
        _value = x;

        // Validation check
        if (_value < 0) _value = 0;

    public Counter() {
        _value = SomeSingleton.Instance.GetDefaultCounterValue();

    public void Increment() {
        SetValue(_value + 1);

    public void Decrement() {
        SetValue(_value - 1);

    public void LogValue() {

note that for simple class like this, it is usually good to mix data and logic inside one class.

However this is not scalable and probably violating single responsibility principle (based on my poor understanding), as this class is responsible to:

  1. Hold the value data (poor-man database?).
  2. Doing some validation check on the value.
  3. Get the value from SomeSingleton.
  4. Operate on the value.
  5. Log the value.

What is the simplest way to separate data and logic for this code to adhere Single Responsibility Principle?

Unique explanation: I wanted to borrow functional programming paradigm to separate data and logic (in this case to different classes), also I'm unable to read other languages such as Java or python, I'm still learning C# myself. can we specify this on C# language only?

Question Credit: Kevin Tanudjaja
Question Reference
Asked August 24, 2019
Posted Under: Programming
2 Answers

From OOP and C# perspective the example code doesn't violate SRP. Data and basic operations over it belong together, that's what classes are. The idea to separate data and logic should be applied on higher level in large applications, e.g. business logic should be separate from data persistence.

One can make other remarks on the code, not related to SRP. Having public method SetValue breaks encapsulation. Also, the usage of singleton is suspicious, it looks like dependency injection should be used in that case.

credit: Rumen Georgiev
Answered August 24, 2019
Your Answer