#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. ...
Комментариев нет:
Отправить комментарий