How do I use a static variable without messing up

2019-07-14 20:37发布

问题:

I have a user class - snippet as below:

public class User
    {
        private int userID;
        private static int nextID = 99;
        private String firstName;
        private String lastName;
        private String email;
        private String password;
        private String fullName;

        public User()
        {
        }

        public User(String firstName, String lastName, String email, String password)
        {
            userID = nextID + 1;
            nextID++;
            this.firstName = firstName;
            this.lastName = lastName;
            fullName = firstName + " " + lastName;
            this.email = email;
            this.password = password;
        }

I want to give users a unique UserID that increments each time a user is instantiated.

I tried doing this with a static int NextID to hold the UserID of the next object and increment it in the constructor after it is used each time.

However, when I tried this, it messed up my unit tests and some of them fail when I Run All Tests but they all still pass when run individually.

Does anyone know how I can achieve this goal without messing up my unit tests?

回答1:

This looks like a design issue.

For example, try separating the concerns of the classes involved.

public interface IUserIdManager {
    int GetNextId();
}

public interface IUserFactory {
    User Create();
    User Create(String firstName, String lastName, String email, String password);
}

Have the user manager implementation depend on the id manager to be used when creating instances.

public class UserFactory : IUserFactory {
    private readonly IUserIdManager ids;
    public UserFactory(IUserIdManager ids) {
        this.ids = ids;
    }

    public User Create() { 
        var user = new User();
        user.UserId = ids.GetNextId();
        return user;
    }

    public User Create(String firstName, String lastName, String email, String password) { 
        var user = new User(firstName, lastName, email, password);
        user.UserId = ids.GetNextId();
        return user;
    }
}

The user class should not be concerned with creating its own id. That is not its responsibility. It should be kept lean as a simple POCO/model to hold data.



回答2:

Posting my production code, based on solution in Answer from @Nkosi above, here. Have given @Nkosi the credit for answering the question but just wanted to show the solution code and say that it worked. Also, thanks for all the comments everyone, it really helped me a lot!

public class UserIDGenerator : IUserIDGenerator
{
    private int nextUserID = 100;

    public int getNextUserID()
    {
        return nextUserID++;
    }
}

public class UserAdministration : IUserAdministration
{
    private List<User> users = new List<User>();

    private IUserIDGenerator userIDGenerator;

    public UserAdministration(IUserIDGenerator userIDGenerator)
    {
        this.userIDGenerator = userIDGenerator;
    }

    public bool addUser(String firstName, String lastName, String email, String password)
    {
        users.Add(new User(userIDGenerator.getNextUserID(), firstName, lastName, email, password));
        return true;
    }
}