Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Считается ли хорошим вариантом создавать объект внутри его класса?

#java #ооп #классы


Привет!  Я начал глубже разбираться в классах и их взаимодействии. 

Я решил создать маленькую программу, которая содержит:


класс test(который содержит метод main);
User(который содержит информацию о пользователе, геттеры и сеттеры для логина и "пароля"
для пользователя);
Menu(В этом классе пока существует один метод, который использует геттеры и сеттеры
класса User, задает ему имя и пароль, такая себе регистрация);


Класс User содержит в себе такой код: 

public class User {
    private String userName;
    private String password;

    public static User user = new User();

    public void setName(String name){
        userName = name;
    }

    public String getName(){
        return userName;
    }

    public void setPassword(String pass){
       password = pass;
    }

    public String getPassword(){
        return password;
    }

}


Когда я создавал обьект пользователя в классе Menu, в методе register, где после
этого и присваивал ему никнейм и пароль, я заметил, что я не смогу использовать этот
объект в других методах и классах, ибо чтобы обратится к нему и получить никнейм, я
должен был бы написать, к примеру в классе test: Menu.user.getName()  , но работать
это не будет.

Поэтому я создал объект в том же классе, где находятся его сеттеры и геттеры. Теперь,
если я хочу обратиться к объекту User, у которого название, к примеру, user

( User user = new User(); ) 

с любого уголка программы, я просто пишу User.user.setName("John");

Считается ли это хорошей практикой, создавать объект в его же классе, (потому-что
иначе я пока не знаю, как к нему обратится из другого метода или класса)? Если существует
правильная альтернатива, как она должна выглядеть?

Буду рад каждому совету, даже если он будет о моем ужасном коде или непонимании,
я приму каждый совет, я уважаю мнение каждого пользователя!

Upd.: тот единственный метод в классе Menu: 

public class Menu {

public static void register(){


    Scanner sc = new Scanner(System.in);

    do {
        System.out.println("Create your nickname:");
        User.user.setName(sc.nextLine());
    }while(User.user.getName().equals(""));

    do {
        System.out.println("Create your password:");
        User.user.setPassword(sc.nextLine());
    }while(User.user.getPassword().equals(""));
}


}
    


Ответы

Ответ 1



Краткий ответ на ваш вопрос - зависит от обстоятельств. В конкретно вашем случае - это очень плохая практика. Теперь детальнее. Строкой public static User user = new User(); вы создаете единый глобальный объект на всю систему. Обычно такие объекты обозначают некоторые константы, как, например, BigInteger.ONE или некоторые интерфейсные объекты. Т.е. объекты не хранящие свое внутреннее состояние, а выполняющие только какие-то действия. Но в любом случае, такие объекты создают с модификатором final, чтобы предотвратить возможность перезаписывания их в любом месте программы User.user = null; В вашем же случае нужно четко представлять область видимости объекта и предоставлять соответствующий уровень доступа. Если вы пишете public static void register(){ ......... User user = new User(); ......... } то такой объект будет виден (и существовать) только в этом методе. Может быть, вам нужно вернуть его из метода public static User register(){ ......... User user = new User(); ......... return user; } и тогда пусть вызывающая сторона заботится о его существовании. В том числе отдает всем заинтересованным в нем объектам. С учетом того, что метод register у вас статический, мне это видится самым адекватным решением. Еще есть вариант сделать этот объект статическим полем класса Menu (но зачем в меню пользователь для меня загадка) class Menu { private static User user; public static User getUser() { return user; } public static void register() { ......... User user = new User(); ......... } } в этом случае мы опять получаем единый глобальный объект, но уже без возможности его перезатирания (но по прежнему остается возможность его несанкционированной модификации) Также можно объявить метод register нестатическим. Тогда и объект будет нестатическим, а обычным полем класса со всеми возможностями первого способа. Но повторюсь - адекватность связи меню и пользователя у меня вызывает сомнения.

Ответ 2



Идеологически Menu вряд ли состоит из User, но скорее всего использует его для своей работы, то есть это зависимость. Зависимости лучше внедрять извне, тогда можно будет добавить ссылки на User в любой объект, который от него зависит. Пусть: public interface AbstractUser {...} public class StandardUser implements AbstractUser {...} public class SpecialUser implements AbstractUser {...} Внедрять зависимости можно через конструктор (когда Menu требует для своей работы User) public class Menu { public class Menu(AbstractUser user) { this.user = user; } private AbstractUser user; } ... var user = new SpecialUser(); var menu = new Menu(user); ... или через поле/сеттер (когда зависимость опциональна и/или существует подходящий умолчательный вариант). public class Menu { public class Menu() { this.user = new StandardUser(); } public void setUser(AbstractUser user) { this.user = user; } private AbstractUser user; } ... var menu = new Menu(); // uses StandardUser as default impl. var user = new SpecialUser(); menu.setUser(user); // switch to optional impl. ...

Комментариев нет:

Отправить комментарий