Skip to content

Instantly share code, notes, and snippets.

@Shtaba09
Created November 6, 2018 18:47
Show Gist options
  • Save Shtaba09/e6d325645692713e24f97efa00068752 to your computer and use it in GitHub Desktop.
Save Shtaba09/e6d325645692713e24f97efa00068752 to your computer and use it in GitHub Desktop.
MVC Pattern
package com.javarush.task.task36.task3608.bean;
public class User implements Cloneable {
private String name;
private final long id;
private int level;
public static final User NULL_USER = new User();
public User(String name, long id, int level) {
this.name = name;
this.id = id;
this.level = level;
}
public User() {
this("", 0, 0);
}
//methods with logic
public boolean isNew() {
return id == 0;
}
public User clone() {
try {
return (User) super.clone();
} catch (CloneNotSupportedException ignored) {
return NULL_USER;
}
}
public User clone(long newId) {
if (this == NULL_USER) return NULL_USER;
return new User(name, newId, level);
}
///// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", level=" + level +
'}';
}
}
package com.javarush.task.task36.task3608.controller;
import com.javarush.task.task36.task3608.bean.User;
import com.javarush.task.task36.task3608.model.MainModel;
import com.javarush.task.task36.task3608.model.Model;
import com.javarush.task.task36.task3608.model.ModelData;
import com.javarush.task.task36.task3608.view.EditUserView;
import com.javarush.task.task36.task3608.view.UsersView;
public class Controller {
private EditUserView editUserView;
private Model model ;
private UsersView usersView;
public void setEditUserView(EditUserView editUserView) {
this.editUserView = editUserView;
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
public void onShowAllUsers(){
model.loadUsers();
usersView.refresh(model.getModelData());
}
public void setUsersView(UsersView usersView) {
this.usersView=usersView;
}
public void onShowAllDeletedUsers() {
model.loadDeletedUsers();
usersView.refresh(model.getModelData());
}
public void onOpenUserEditForm(long id) {
model.loadUserById(id);
editUserView.refresh(model.getModelData());
}
public void onUserDelete(long id){
model.deleteUserById(id);
usersView.refresh(model.getModelData());
}
public void onUserChange(String name, long id, int level) {
model.changeUserData(name, id, level);
usersView.refresh(model.getModelData());
}
}
package com.javarush.task.task36.task3608.dao.mock;
import com.javarush.task.task36.task3608.bean.User;
import java.util.LinkedList;
import java.util.List;
public class DataSource {
private static DataSource ourInstance = new DataSource();
public static DataSource getInstance() {
return ourInstance;
}
private DataSource() {
}
private List<User> users = new LinkedList<User>() {{
add(new User("Ivanov", 123l, 1));
add(new User("Petrov", 124l, 2));
add(new User("Petrov", 125l, 1));
add(new User("Sidorov", 126l, 2));
}};
private long maxUserId = 126l;
public List<User> getUsers() {
return users;
}
public User createOrUpdate(User newUser) {
if (newUser == User.NULL_USER)
return User.NULL_USER;
//new User
if (newUser.getId() == 0)
return createNewUser(newUser);
else
return updateUser(newUser);
}
private User createNewUser(User newUser) {
User clone = newUser.clone(++maxUserId);
users.add(clone);
return clone;
}
private User updateUser(User newUser) {
for (User user : users) {
if (user.getId() == newUser.getId()) {
user.setName(newUser.getName());
user.setLevel(newUser.getLevel());
return user;
}
}
//if we didn't find such a user
return User.NULL_USER;
}
}
package com.javarush.task.task36.task3608.dao;
import com.javarush.task.task36.task3608.bean.User;
import com.javarush.task.task36.task3608.dao.mock.DataSource;
import java.util.ArrayList;
import java.util.List;
public class UserDao {
private DataSource dataSource = DataSource.getInstance();
public User getUserById(long id) {
List<User> users = dataSource.getUsers();
for (User user : users) {
if (user.getId() == id) {
return user.clone();
}
}
return User.NULL_USER;
}
public List<User> getUsersByName(String name) {
if (name == null || name.trim().isEmpty()) throw new IllegalArgumentException();
List<User> users = dataSource.getUsers();
List<User> result = new ArrayList<>();
for (User user : users) {
if (name.equals(user.getName())) {
addUserToResult(result, user);
}
}
return result;
}
public List<User> getAllUsers() {
List<User> users = dataSource.getUsers();
List<User> result = new ArrayList<>();
for (User user : users) {
addUserToResult(result, user);
}
return result;
}
public List<User> getUsersByLevel(int level) {
if (level < 1) throw new IllegalArgumentException();
List<User> users = dataSource.getUsers();
List<User> result = new ArrayList<>();
for (User user : users) {
if (level == user.getLevel()) {
addUserToResult(result, user);
}
}
return result;
}
public void addUserToResult(List<User> result, User user) {
User clone = user.clone();
//skip bad users
if (clone != User.NULL_USER) {
result.add(clone);
}
}
public User createOrUpdate(User user) {
return dataSource.createOrUpdate(user);
}
public User getUsersById(long userId) {
if (userId < 1) throw new IllegalArgumentException();
List<User> users = dataSource.getUsers();
for (User user : users) {
if (userId == user.getId()) {
return user;
}
}
return User.NULL_USER;
}
}
package com.javarush.task.task36.task3608.model;
import com.javarush.task.task36.task3608.bean.User;
import java.util.ArrayList;
public class FakeModel implements Model {
private ModelData modelData = new ModelData();
@Override
public ModelData getModelData() {
return modelData;
}
@Override
public void loadUsers() {
ArrayList<User> userList = new ArrayList<User>();
userList.add(new User("Ivanov", 1, 11));
userList.add(new User("Petrov", 2, 12));
modelData.setUsers(userList);
}
@Override
public void loadDeletedUsers() {
throw new UnsupportedOperationException();
}
@Override
public void loadUserById(long id) {
throw new UnsupportedOperationException();
}
@Override
public void deleteUserById(long id) {
throw new UnsupportedOperationException();
}
@Override
public void changeUserData(String name, long id, int level) {
throw new UnsupportedOperationException();
}
}
package com.javarush.task.task36.task3608.model;
import com.javarush.task.task36.task3608.Util;
import com.javarush.task.task36.task3608.bean.User;
import com.javarush.task.task36.task3608.model.service.UserService;
import com.javarush.task.task36.task3608.model.service.UserServiceImpl;
import java.util.List;
public class MainModel implements Model {
private UserService userService = new UserServiceImpl();
private ModelData modelData = new ModelData();
@Override
public ModelData getModelData() {
return modelData;
}
@Override
public void loadUsers() {
List<User> users = userService.getUsersBetweenLevels(1, 100);
modelData.setUsers(getAllUsers());
modelData.setDisplayDeletedUserList(false);
}
@Override
public void loadDeletedUsers() {
List<User> users = userService.getAllDeletedUsers();
modelData.setUsers(users);
modelData.setDisplayDeletedUserList(true);
}
@Override
public void loadUserById(long id) {
User user = userService.getUsersById(id);
modelData.setActiveUser(user);
modelData.setDisplayDeletedUserList(false);
}
@Override
public void deleteUserById(long id) {
userService.deleteUser(id);
modelData.setUsers(getAllUsers());
}
@Override
public void changeUserData(String name, long id, int level) {
userService.createOrUpdateUser(name, id, level);
modelData.setUsers(getAllUsers());
}
private List<User> getAllUsers(){
List<User> users = userService.getUsersBetweenLevels(1, 100);
return userService.filterOnlyActiveUsers(users);
}
}
package com.javarush.task.task36.task3608.model;
public interface Model {
ModelData getModelData();
void loadUsers();
void loadDeletedUsers();
void loadUserById(long id);
void deleteUserById(long id);
void changeUserData(String name, long id, int level);
}
package com.javarush.task.task36.task3608.model;
import com.javarush.task.task36.task3608.bean.User;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ModelData {
private List<User> users ;
private User activeUser;
private boolean displayDeletedUserList;
public boolean isDisplayDeletedUserList() {
return displayDeletedUserList;
}
public void setDisplayDeletedUserList(boolean displayDeletedUserList) {
this.displayDeletedUserList = displayDeletedUserList;
}
public User getActiveUser() {
return activeUser;
}
public void setActiveUser(User activeUser) {
this.activeUser = activeUser;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
package com.javarush.task.task36.task3608.model.service;
import com.javarush.task.task36.task3608.bean.User;
import java.util.List;
public interface UserService {
public User deleteUser(long id);
public User createOrUpdateUser(String name, long id, int level);
public List<User> getUsersByName(String name);
public List<User> getAllDeletedUsers();
public List<User> getUsersBetweenLevels(int fromLevel, int toLevel);
List<User> filterOnlyActiveUsers(List<User> allUsers);
User getUsersById(long userId);
}
package com.javarush.task.task36.task3608.model.service;
import com.javarush.task.task36.task3608.Util;
import com.javarush.task.task36.task3608.bean.User;
import com.javarush.task.task36.task3608.dao.UserDao;
import java.util.ArrayList;
import java.util.List;
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDao();
@Override
public User deleteUser(long id) {
User user = userDao.getUserById(id);
Util.markDeleted(user);
userDao.createOrUpdate(user);
return user;
}
@Override
public User createOrUpdateUser(String name, long id, int level) {
User user = new User(name, id, level);
return userDao.createOrUpdate(user);
}
@Override
public List<User> getUsersByName(String name) {
return userDao.getUsersByName(name);
}
@Override
public List<User> getAllDeletedUsers() {
List<User> result = new ArrayList<>();
for (User user : userDao.getAllUsers()) {
if (Util.isUserDeleted(user)) {
result.add(user);
}
}
return result;
}
@Override
public List<User> getUsersBetweenLevels(int fromLevel, int toLevel) {
//it's better to get all users from DAO by one DB request, but we will use what we have
List<User> result = new ArrayList<>();
for (int i = fromLevel; i <= toLevel; i++) {
result.addAll(userDao.getUsersByLevel(i));
}
return result;
}
@Override
public List<User> filterOnlyActiveUsers(List<User> allUsers) {
//will not change allUsers list, create new one instead of that
List<User> result = new ArrayList<>();
for (User user : allUsers) {
if (User.NULL_USER != user && !Util.isUserDeleted(user)) {
result.add(user);
}
}
return result;
}
@Override
public User getUsersById(long userId) {
return userDao.getUsersById(userId);
}
}
package com.javarush.task.task36.task3608;
import com.javarush.task.task36.task3608.controller.Controller;
import com.javarush.task.task36.task3608.model.MainModel;
import com.javarush.task.task36.task3608.model.Model;
import com.javarush.task.task36.task3608.view.EditUserView;
import com.javarush.task.task36.task3608.view.UsersView;
public class Solution {
public static void main(String[] args) {
Model model = new MainModel();
UsersView usersView = new UsersView();
EditUserView editUserView =new EditUserView();
Controller controller = new Controller();
usersView.setController(controller);
editUserView.setController(controller);
controller.setModel(model);
controller.setUsersView(usersView);
controller.setEditUserView(editUserView);
usersView.fireEventShowAllUsers();
usersView.fireEventOpenUserEditForm( 126L);
editUserView.fireEventUserDeleted(124L);
editUserView.fireEventUserChanged("Petrov",125L,8);
usersView.fireEventShowDeletedUsers();
}
}
package com.javarush.task.task36.task3608;
import com.javarush.task.task36.task3608.bean.User;
public final class Util {
public static final String DELETED_MARKER = " (deleted)";
public static boolean isUserDeleted(User user) {
return user.getName().endsWith(DELETED_MARKER);
}
public static void markDeleted(User user) {
if (User.NULL_USER != user && !Util.isUserDeleted(user)) {
user.setName(user.getName() + DELETED_MARKER);
}
}
}
package com.javarush.task.task36.task3608.view;
import com.javarush.task.task36.task3608.bean.User;
import com.javarush.task.task36.task3608.controller.Controller;
import com.javarush.task.task36.task3608.model.ModelData;
public class EditUserView implements View{
private Controller controller;
@Override
public void refresh(ModelData modelData) {
System.out.println("User to be edited:");
System.out.println("\t" + modelData.getActiveUser().toString());
System.out.println("===================================================");
}
@Override
public void setController(Controller controller) {
this.controller=controller;
}
public void fireEventUserDeleted(long id){
controller.onUserDelete(id);
}
public void fireEventUserChanged(String name, long id, int level){
controller.onUserChange(name, id, level);
}
}
package com.javarush.task.task36.task3608.view;
import com.javarush.task.task36.task3608.controller.Controller;
import com.javarush.task.task36.task3608.model.ModelData;
import com.javarush.task.task36.task3608.bean.User;
import com.javarush.task.task36.task3608.model.service.UserService;
import com.javarush.task.task36.task3608.model.service.UserServiceImpl;
public class UsersView implements View {
private UserService userService = new UserServiceImpl();
private Controller controller = new Controller() ;
@Override
public void refresh(ModelData modelData) {
System.out.println(!modelData.isDisplayDeletedUserList()? "All users:" : "All deleted users:");
for (User user : modelData.getUsers()) {
System.out.println("\t" + user.toString());
}
System.out.println("===================================================");
}
@Override
public void setController(Controller controller) {
this.controller=controller;
}
public void fireEventShowAllUsers(){
controller.onShowAllUsers();
}
public void fireEventShowDeletedUsers() {
controller.onShowAllDeletedUsers();
}
public void fireEventOpenUserEditForm(long id) {
controller.onOpenUserEditForm(id);
}
}
package com.javarush.task.task36.task3608.view;
import com.javarush.task.task36.task3608.model.ModelData;
import com.javarush.task.task36.task3608.controller.Controller;
public interface View {
void refresh(ModelData modelData);
void setController(Controller controller);
}
taskKey="com.javarush.task.task36.task3608.big09"
MVC (9)
Это последнее задание по MVC.
1. Следуя принципу MVC аналогично реализации предыдущих методов сделай следующее:
напиши логику обновления пользователя. После обновления должен отображаться список пользователей.
Распредели следующие методы по классам MVC:
public void fireEventUserChanged(String name, long id, int level)
public void onUserChange(String name, long id, int level)
public void changeUserData(String name, long id, int level)
где name и level - это новые значения для пользователя с выбранным id.
Примечание: метод, который ты собираешься добавить в Вью нужно добавить в EditUserView.
2. Добавь в main вызов fireEventUserChanged перед вызовом метода fireEventShowDeletedUsers().
3. Добавь в интерфейс Model метод, который ты поместил в Модель, реализуй его в FakeModel: выброси UnsupportedOperationException.
Требования:
1. Необходимо определить правильное расположение метода fireEventUserChanged(String name, long id, int level) и реализовать этот метод.
2. Необходимо определить правильное расположение метода onUserChange(String name, long id, int level) и реализовать этот метод.
3. Необходимо определить правильное расположение метода void changeUserData(String name, long id, int level) и реализовать этот метод.
4. В методе main необходимо вызвать метод fireEventUserChanged(String, long, int) перед вызовом метода fireEventShowDeletedUsers().
5. Интерфейс Model должен содержать объявление метода, который ты ранее реализовал в классе MainModel.
6. В классе FakeModel в теле метода, помещенного в интерфейс Model, необходимо бросить UnsupportedOperationException.
MVC (8)
1. Следуя принципу MVC аналогично реализации предыдущих методов сделай следующее:
напиши логику удаления пользователя. После удаления должен отображаться список пользователей.
Распредели следующие методы по классам MVC:
public void fireEventUserDeleted(long id)
public void onUserDelete(long id)
public void deleteUserById(long id)
Примечание: метод, который ты собираешься добавить в Вью нужно добавить в EditUserView.
2. Добавь в main вызов fireEventUserDeleted(124L) перед вызовом метода fireEventShowDeletedUsers().
3. Выполни рефакторинг класса MainModel. Теперь, когда есть удаленные пользователи, часть методов стала работать неправильно.
Почти во всех методах, где требуется список пользователей, нужно работать только с активными(живыми) пользователями.
Вынеси в отдельный приватный метод List<User> getAllUsers() получение списка всех активных пользователей.
Фильтрация активных пользователей у тебя уже есть - метод List<User> filterOnlyActiveUsers(List<User> allUsers).
Отрефактори все методы, которые используют список пользователей. Они должны использовать список живых пользователей.
4. Добавь в интерфейс Model метод, который ты поместил в Модель, реализуй его в FakeModel: выброси UnsupportedOperationException.
MVC (7)
1. Распредели методы по классам MVC:
public void onOpenUserEditForm(long userId) {
...loadUserById(userId);
...refresh(...getModelData());
}
public void fireEventOpenUserEditForm(long id) {
...onOpenUserEditForm(id);
}
public void loadUserById(long userId) {
User user = userService.getUsersById(userId);
...setActiveUser(user);
}
!!!! Пользователь видит Вью со списком пользователей, нажимает на одного из них, запрос идет на сервер,
выгребаем новые данные и отображаем другую Вью, которая относится к одному выбранному пользователю.
Учти это при реализации этого задания.
2. Добавь в метод main открытие формы редактирования для пользователя с id=126 перед вызовом метода fireEventShowDeletedUsers().
3. Добавь в интерфейс Model метод, который ты поместил в Модель, реализуй его в FakeModel: выброси UnsupportedOperationException.
MVC (6)
Функционал отображения удаленных пользователей есть, а самих таких пользователей нет. Давай это исправим.
Давай сделаем новую Вью, которая будет отвечать за редактирование одного конкретного пользователя.
UsersView отображает список пользователей.
EditUserView будет отображать данные о редактировании конкретного пользователя.
Для этого нам сначала нужен этот выбранный пользователь.
Как и любые данные его поместим в ModelData.
1. Создай в ModelData поле User activeUser с геттером и сеттером (Alt+Insert -> Getter and Setter).
2. Аналогично UsersView создай EditUserView.
Логика метода refresh:
2.1. Вывести в консоль "User to be edited:".
2.2. С новой строки вывести табуляцию и активного пользователя.
2.3. С новой строки вывести разделитель "===================================================".
3. Создай в контроллере поле EditUserView editUserView с сеттером.
Когда наши данные выводятся в консоль, то совсем не понятно, список каких пользователей - удаленных или нет - выводится.
Давай сделаем так, чтобы Вью отображала эту информацию. Все данные для отображения хранятся в Моделе. Поэтому:
4. создай в ModelData поле boolean displayDeletedUserList с геттером и сеттером.
5. Измени метод refresh в UsersView так, чтобы он отображал "All users:" либо "All deleted users:"
в зависимости от того, какие пользователи находятся в списке. Добавь в необходимые методы модели изменение displayDeletedUserList.
MVC (5)
В сервисе есть метод, который возвращает всех удаленных пользователей. Давай их отобразим.
1. Распредели методы по классам MVC:
public void fireEventShowDeletedUsers() {
...onShowAllDeletedUsers();
}
public void onShowAllDeletedUsers() {
...loadDeletedUsers();
}
public void loadDeletedUsers() {
List<User> users = userService.getAllDeletedUsers();
}
Не забудь, что данные, полученные с сервера, необходимо положить в ModelData. А потом обновить view.
Добавь это самостоятельно в нужные методы.
2. Добавь в Solution.main вызов нового метода, который ты поместил в view.
3. Добавь в интерфейс Model метод, который ты поместил в Модель, реализуй его в FakeModel: выброси UnsupportedOperationException.
MVC (4)
Пора заменять нашу фейковую Модель на реальную, которая будет получать данные из DataSource.
В пакет model.service я добавил сервис для работы с пользователями.
Также в корне этой задачи ты найдешь утильный класс Util.
1. Аналогично FakeModel создай модель MainModel.
2. Т.к. Модель обращается к сервисам, то в MainModel создай поле UserService userService, инициализируй объектом.
3. Реализуй логику метода loadUsers:
3.1. Достань всех пользователей между 1 и 100 уровнями. (Метод getUsersBetweenLevels(1, 100)).
3.2. Положи всех пользователей в modelData.
4. Обнови Solution.main: замени FakeModel на MainModel.
Преимущества MVC в том, что в любой момент времени легко можно заменить любую часть паттерна.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment