Форум программистов, компьютерный форум, киберфорум
Наши страницы

ООП и паттерны

Войти
Регистрация
Восстановить пароль
 
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
#1

Паттерн MVC - ООП и паттерны

14.02.2017, 16:04. Просмотров 790. Ответов 14
Метки нет (Все метки)

Здравствуйте, уважаемые форумчане!
Написал небольшую программу, следуя шаблону MVC (Model-View-Controller).
Посмотрите, пожалуйста, всё ли я правильно делаю. Может нарушены основные принципы шаблона, может нарушены принципы SOLID или даже нарушены принципы ООП. Или просто стиль написания кода у меня неудобочитаемый. А то пишу я в основном проекты, код которых никто не читает. Прога работает, вроде не падает ну и ладно. Хочется, чтобы посмотрели на мой код со стороны, и, по возможности, указали на «кривые» части кода.
Задача: «Создать консольное приложение для библиотеки, с возможность добавления,
удаления и изменения книг в библиотеке. Реализовать возможность поиска книг в библиотеке по названию книги, автору и году издания
».
Подойдут любые ваши комментарии к коду: именование переменных, методов, классов, раздутость методов, классов, не следование определенным принципам, всё что угодно!
Заранее спасибо!
View.java:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.Scanner;
 
public class View {
    
    // 
    public void sendMessage(String string){
        System.out.println(string);
    }
    
    // Menu
    public void showMenu(){
        System.out.println("What would you like to do? Enter the number of menu:");
        System.out.println("1.Search a book in library");
        System.out.println("2.Add book in to library");
        System.out.println("3.Delete book from library");
        System.out.println("4.Change book");
        System.out.println("5.Show all books");
        System.out.println("0.Exit from library");
    }
    
    // Sub-menu for search book in the library
    public void showSubMenu(){
        System.out.println("What would you like to do? Enter the number of menu:");
        System.out.println("1.Search the book by author");
        System.out.println("2.Search the book by name");
        System.out.println("3.Search the book by year of publication");
        System.out.println("9.To the previous menu");
        System.out.println("0.Exit from library");
    }
    
    
    public String getData(){
        Scanner data = new Scanner(System.in);
        return data.nextLine();
    }
    
    public static void main(String[] args){
        new Controller();
    }
}

Book.java:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class Book {
    // Fields
    private String author;
    private String name;
    private String city;
    private String publishingHouse;
    private int year;
    private int pages;
    
    // Constructors
    public Book(String author,String name,String city,String publishingHouse,int year,int pages){
        this.author=author;
        this.name=name;
        this.city=city;
        this.publishingHouse=publishingHouse;
        this.year=year;
        this.pages=pages;
    }
    
    public Book() {
        
    }
    
    // Setters/Getters
    public void setAuthor(String author){
        this.author=author;
    }
    public void setName(String name){
        this.name=name;
    }
    public void setCity(String city){
        this.city=city;
    }
    public void setPublishingHouse(String publishingHouse){
        this.publishingHouse=publishingHouse;
    }
    public void setYear(String year){
        int iYear=0;
        try{
            iYear=Integer.parseInt(year);
        }
        catch(NumberFormatException e){
            System.out.println("Incorrect entered data");
        }
        this.year=iYear;
    }
    public void setPages(String pages){
        int countPages=0;
        try{
            countPages=Integer.parseInt(pages);
        }
        catch(NumberFormatException e){
            System.out.println("Incorrect entered data");
        }        
        this.pages=countPages;
    }
    public String getAuthor(){
        return author;
    }
    public String getName(){
        return name;
    }
    public String getCity(){
        return city;
    }
    public String getPublishingHouse(){
        return publishingHouse;
    }
    public int getYear(){
        return year;
    }
    public int getPages(){
        return pages;
    }
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.02.2017, 16:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Паттерн MVC (ООП и паттерны):

Чем отличается паттерн MVVM от MVC? - ООП и паттерны
И если можно то поподробней о них. MVVM имеется в виду относительно C# WPF.

Декоратор(паттерн) - ООП и паттерны
Привет, у меня есть вектор std::vector<cShape*> figures; помещаю в него 2 квадрата cShape* sq1 = new cSquare("sq1", 100); ...

Паттерн мост - ООП и паттерны
Добрый день! Уважаемые форумчане подкиньте пожалуйста идейку по реализации моста. У меня есть два интерфейса: IDBForm и IManager. ...

Паттерн command - ООП и паттерны
Реализую клиент серверное приложение(сокеты). Для выполнения команд от пользователя имею функцию. Для выполнения команд от пользователя...

паттерн Observer - ООП и паттерны
Гуру программирования, просветите по данному сабжу (расскажите человеческим языком/направьте ссылками), очень интересно:) p.s. ...

Паттерн Одиночка - ООП и паттерны
Проблема: Написал 4 паттерна, хотел раскинуть на 5 пректов (4 паттерна и main, где они срабатывают ). (если не задействовать паттерн...

14
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
14.02.2017, 16:04  [ТС] #2
Controller.java:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
import java.util.ArrayList;
 
public class Controller {
    private View view = new View(); // May be need to use the interface?
    private static ArrayList<Book> library= new ArrayList<Book>();
    
    public Controller(){
        // Several books added in library for example...
        Book book0 = new Book("Пушкин А.С.","Лукоморье","М.","Ручеек",2006,389);
        Book book1 = new Book("Пушкин А.С.","Сказ о царе Салтане","М.","Ручеек",2005,234);
        Book book2 = new Book("Гоголь Н.В.","Мертвые души","М.","Классик",2002,5);
        library.add(book0);
        library.add(book1);
        library.add(book2);
        // ...Several books added in library for example
        view.sendMessage("Hello! We are glad to see you in our library!");
        toDoList(); // Main menu
    }
    
    // Main menu
    private void toDoList(){
        view.showMenu();
        String listItem=view.getData();
        switch(listItem){
        case "1": 
            toDoSubSearchList(); 
            break;
        case "2":
            Book book = new Book();
            if(addBookInLibrary(book)){
                library.add(book);
            }
            toDoList();
            break;
        case "3": 
            deleteBookFromLibrary(); 
            toDoList();
            break;
        case "4": 
            changeBookInLibrary(); 
            toDoList();
            break;
        case "5":
            showAllBooks();
            view.sendMessage("");
            toDoList();
            break;
        case "0":
            view.sendMessage("Good bye!");
            break;
        default:
            view.sendMessage("Entered data is incorrect!");
            toDoList(); 
            break;
        }
    }
    
    // Searches
    private void toDoSubSearchList(){
        view.showSubMenu();
        String subListItem=view.getData();
        switch(subListItem){
        case "1": 
            view.sendMessage("Enter author of a book:");
            searchBookByAuthor(view.getData());
            toDoSubSearchList(); 
            break;
        case "2": 
            view.sendMessage("Enter name of a book:");
            searchBookByName(view.getData());
            toDoSubSearchList(); 
            break;
        case "3": 
            view.sendMessage("Enter year, when book was published:");
            searchBookByYear(view.getData());
            toDoSubSearchList(); 
            break;
        case "9": 
            toDoList(); 
            break;
        case "0":
            view.sendMessage("Good bye!");
            break;
        default: 
            view.sendMessage("Entered data is incorrect!");
            toDoSubSearchList(); 
            break;
        }
    }
    
    private void searchBookByAuthor(String author){
        boolean bookHasFlag=false;
        for (Book book:library){
            if(book.getAuthor().equals(author)){
                viewBook(book);
                bookHasFlag=true;
            }
        }
        if(!bookHasFlag){
            view.sendMessage("Sorry, the search has not given any results!");
        }
    }
 
    private ArrayList<Book> searchBooksByAuthor(String author){
        ArrayList<Book> books = new ArrayList<Book>();
        boolean bookHasFlag=false;
        for (Book book:library){
            if(book.getAuthor().equals(author)){
                books.add(book);
                viewBook(book);
                bookHasFlag=true;
            }
        }
        if(!bookHasFlag){
            view.sendMessage("Sorry, the search has not given any results!");
        }
        return books;
    }
    
    private ArrayList<Book> searchBooksByName(String name, ArrayList<Book> books){
        ArrayList<Book> foundBooks = new ArrayList<Book>();
        boolean bookHasFlag=false;
        for (Book book:books){
            if(book.getName().equals(name)){
                foundBooks.add(book);
                viewBook(book);
                bookHasFlag=true;
            }
        }
        if(!bookHasFlag){
            view.sendMessage("Sorry, the search has not given any results!");
        }
        return foundBooks;
    }
    
    private void searchBookByName(String name){
        boolean bookHasFlag=false;
        for (Book book:library){
            if(book.getName().equals(name)){
                viewBook(book);
                bookHasFlag=true;
            }
        }
        if(!bookHasFlag){
            view.sendMessage("Sorry, the search has not given any results!");
        }
    }
    
    private void searchBookByYear(String year){
        boolean bookHasFlag=false;
        for (Book book:library){
            if(year.equals(String.valueOf(book.getYear()))){
                viewBook(book);
                bookHasFlag=true;
            }
        }
        if(!bookHasFlag){
            view.sendMessage("Sorry, the search has not given any results!");
        }
    }
    // End of searches
    
    // Add book in library
    private boolean addBookInLibrary(Book book){
        boolean saveChanges=false;
        boolean correctData=false;
        view.sendMessage("Enter author of a book:");
        book.setAuthor(view.getData());
        view.sendMessage("Enter name of a book:");
        book.setName(view.getData());
        view.sendMessage("Enter city where book was published:");
        book.setCity(view.getData());
        view.sendMessage("Enter name of publishing house, where book was published:");
        book.setPublishingHouse(view.getData());
        view.sendMessage("Enter year, when book was published:");
        book.setYear(view.getData());
        view.sendMessage("Enter count pages of a book:");
        book.setPages(view.getData());
        view.sendMessage("Save changes?");
        view.sendMessage("1.Yes");
        view.sendMessage("2.No");
        while(!correctData){
            switch(view.getData()){
                case "1": 
                    saveChanges=true; 
                    correctData=true;
                    break;
                case "2": 
                    saveChanges=false; 
                    correctData=true;
                    break;
                default: 
                    view.sendMessage("Entry data is incorrect. Try again");
                    correctData=false;
                    break;
            }
        }
        return saveChanges;
    }
    
    private boolean addBookIntoIndexOfLibrary(Book book,int index){
        boolean saveChanges=false;
        boolean correctData=false;
        view.sendMessage("Enter author of a book:");
        book.setAuthor(view.getData());
        view.sendMessage("Enter name of a book:");
        book.setName(view.getData());
        view.sendMessage("Enter city where book was published:");
        book.setCity(view.getData());
        view.sendMessage("Enter name of publishing house, where book was published:");
        book.setPublishingHouse(view.getData());
        view.sendMessage("Enter year, when book was published:");
        book.setYear(view.getData());
        view.sendMessage("Enter count pages of a book:");
        book.setPages(view.getData());
        view.sendMessage("Save changes?");
        view.sendMessage("1.Yes");
        view.sendMessage("2.No");
        while(!correctData){
            switch(view.getData()){
                case "1": 
                    saveChanges=true; 
                    correctData=true;
                    break;
                case "2": 
                    saveChanges=false; 
                    correctData=true;
                    break;
                default: 
                    view.sendMessage("Entry data is incorrect. Try again");
                    correctData=false;
                    break;
            }
        }
        return saveChanges;
    }
    
    // End of add book
    
    // Delete book from library
    private void deleteBookFromLibrary(){
        if(library.size()==0){
            view.sendMessage("The library is empty!");
        }
        else{
            ArrayList<Book> books = new ArrayList<Book>();
            ArrayList<Book> subBooks = new ArrayList<Book>();
            view.sendMessage("Enter author of a book:");
            String author=view.getData();
            books=searchBooksByAuthor(author);
            if(books.size()==1){
                library.remove(books.get(0));
            }
            else if(books.size()>=2){
                view.sendMessage("The library contains a several of books authored by the "+author+".");
                view.sendMessage("Enter name of a book:");
                String name=view.getData();
                //books = new ArrayList<Book>();
                subBooks=searchBooksByName(name,books);
                if(subBooks.size()!=0){
                    library.remove(books.get(0));
                }
            }
        }
    }
    // End of delete from library
    
    // Change book in library
    private void changeBookInLibrary(){
        if(library.size()==0){
            view.sendMessage("The library is empty!");
        }
        else{
            ArrayList<Book> books = new ArrayList<Book>();
            ArrayList<Book> subBooks = new ArrayList<Book>();
            view.sendMessage("Enter author of a book:");
            String author=view.getData();
            books=searchBooksByAuthor(author);
            Book book = new Book();
            if(books.size()==1){
                int index = library.indexOf(books.get(0));
                if(addBookIntoIndexOfLibrary(book,index)){
                    library.remove(index);
                    library.add(index, book);
                }
            }
            else if(books.size()>=2){
                view.sendMessage("The library contains a several of books authored by the "+author);
                view.sendMessage("Enter name of a book:");
                String name=view.getData();
                //books = new ArrayList<Book>();
                subBooks=searchBooksByName(name,books);
                if(subBooks.size()!=0){
                    int index = library.indexOf(books.get(0));
                    if(addBookIntoIndexOfLibrary(book,index)){
                        library.remove(index);
                        library.add(index, book);
                    }
                }
            }
        }
    }
    // End of change all books
    
    // Show all books
    private void showAllBooks(){
        if (library.size()==0){
            view.sendMessage("The library is empty!");
        }
        else{
            for(Book book:library){
                viewBook(book);
            }
        }
    }
    
    // Show one book
    private void viewBook(Book book){
        view.sendMessage(book.getAuthor()+" "+book.getName()+" / "+book.getCity()+": "+book.getPublishingHouse()+", "+book.getYear()+". - "+book.getPages()+" с.");
    }
}
0
Вложения
Тип файла: rar Library.rar (9.6 Кб, 6 просмотров)
Shamil1
Модератор
1822 / 1185 / 225
Регистрация: 26.03.2015
Сообщений: 4,362
14.02.2017, 16:36 #3
ТТУК
0
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
14.02.2017, 17:10  [ТС] #4
Цитата Сообщение от Shamil1 Посмотреть сообщение
ТТУК
Как с эти обычно борются? Добавить класс-помощник, или классы-помощники? Что можно вынести в другой класс/классы из контроллера? Как бы Вы поступили?
0
Shamil1
Модератор
1822 / 1185 / 225
Регистрация: 26.03.2015
Сообщений: 4,362
14.02.2017, 23:23 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Выделите бизнес-логику. Поделите её на независимые подзадачи и для каждой создайте класс.

Добавлено через 2 минуты
В Вашем случае напрашиваются классы:
class Book
class BookRepository : IBookRepository
class BookService : IBookService

Добавлено через 2 часа 0 минут
Класс Book содержит данные книги (название и прочие).

Интерфейс IBookRepository отвечает за хранение книг (редактирование, поиск и т.п.)

Клаcc SomeBookRepository реализует интерфейс IBookRepository (например, хранение книг в файле или базе данных).

Класс TestBookRepository - фиктивное тестовое хранилище, основанное на списке (ArrayList<Book> library из Вашего кода).

Класс BookManager - содержит методы по работе с книгами. Сохранение, валидация, поиск и т.п.
Конструктор принимает IBookRepository в качестве параметра. Для тестов будете передавать в него экземпляр TestBookRepository.

Интерфейс IClientLibraryService - содержит методы по работе с книгами для клиента (читателя). Фактически, это фасад для BookManager и прочих классов для работы с книгами (у Вас других классов, кроме BookManager, нет). Констурктор класса, реализующего IClientLibraryService, будет принимать BookManager в качестве параметра.
Аналогично, у Вас могут быть интерфейсы для библиотекаря, администратора и т.п.

Контроллер будет принимать BookManager в качестве параметра конструктора.
Приложение будет создавать экземпляр контроллера, а так же все классы, которые нужны, чтобы инициализировать контроллер.

Добавлено через 3 часа 45 минут
es_,
Обратите внимание на класс BookManager. Он содержит поведение для книг. Адепты того ООП, которое было популярно в прошлом веке, скажут Вам, что этот класс не нужен. Класс Book должен содержать и данные, и поведение для книг. Тем более, что примерно так описывают ООП в учебниках для начинающих. Но у такого подхода есть два недостатка.

Маленький недостаток.
Если у Вас будет другой модуль, в котором используются книги, но не их поведение (например, у авторов будет свойство "список книг"), то этот модуль будет невольно зависеть от поведения книг. Например, если Вы поменяете максимальную длину названия книги (и метод валидации), то Вам придётся пересобрать модуль с авторами.
Для решения этой проблемы можно использовать в модуле с авторами другой класс Book2. Но придётся также добавить класс BookDTO для передачи данных из одного модуля в другой и четыре метода для преобразований Book2 <-> BookDTO <-> Book.

Большая проблема.
Какое поведение у Ваших книг? Get, Search, Update и т.п. Когда Вы начнёте писать класс для других объектов (например, Авторов), Вы сразу заметите, что у них поведение почти такое же. Но делать общего предка для книг и авторов не только неестественно (в какой метод Вы собираетесь передавать и книги, и авторов?), но и неудобно (без плясок с бубном не получится). Значит копипаст... А BookManager и AuthorManager могут быть пронаследованы от одного класса EntityManager<T>, содержащего 90% их кода. При этом BookManager и AuthorManager не будут связаны наследованием, потому что EntityManager<Book> и EntityManager<Author> - это совершенно разные классы, хотя и используют один и тот же код. При этом никаких "заковырок" типа по ошибке вместо Book в какой-то метод передали Author.
4
asmquest
Заблокирован
15.02.2017, 00:37 #6
Цитата Сообщение от Shamil1 Посмотреть сообщение
Маленький недостаток.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Большая проблема.
основная проблема в плюсах головного мозга.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Обратите внимание на класс BookManager. Он содержит поведение для книг.
все что вы тут горячо проповедуете, никакого отношениия к ООП не имеет. Вы не понимаете, что такое ООП.
Поведение объекта не может содержать никто и ничто кроме самого объекта. Обьект представлен в мире своим поведением, нет поведения -- нет и объекта.

Другое дело, что поведение может быть делегированно. Но это относится только к реализации, клиент должен быть абстрагирован от реализации поведения, в том числе и синтаксически.
0
Shamil1
15.02.2017, 02:11
  #7

Не по теме:

es_,
На asmquest не обращайте внимания. Если хотите лично убедиться, чего стоят его слова, посмотрите, какие темы он создаёт на форуме и что там пишет. Ему уже указывали, что его теории - для раздела http://www.cyberforum.ru/unrecognised-theory/ или http://www.cyberforum.ru/holywars/.

з.ы. На другом форуме его уже банили несколько раз, а на этом пока отделывается предупреждениями.

0
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
15.02.2017, 08:52  [ТС] #8
Shamil1, Спасибо большое за подробное описание, буду разбираться и пробовать реализовать "красиво"!

Не по теме:

Ага, я заметил - видел его комменты в некоторых темах

0
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
02.03.2017, 16:55  [ТС] #9
Здравствуйте, Shamil1! Нашел время, чтобы вернуться к проекту Библиотека.
Начал реализовывать программу по вышеописанной Вами схеме, и вот задумался: где мне реализовать, допустим, добавление книги в библиотеку. Сейчас делаю так:
в контроллере в меню выбора:
Java
1
2
3
4
5
6
7
        case "2": // меню выбора добавления книги в библиотеку
            Book book = new Book();
            if(addBookInLibrary(book)){
                _bookManager.addBookInLibrary(book); // Используя bookManager, записываем либо в фиктивную библиотеку, либо в БД
            }
            toDoList();
            break;
и всё так же в контроллере:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    private boolean addBookInLibrary(Book book){
        boolean saveChanges=false;
        boolean correctData=false;
        view.sendMessage("Enter author of a book:");
        book.setAuthor(view.getData());
        view.sendMessage("Enter name of a book:");
        book.setName(view.getData());
        view.sendMessage("Enter city where book was published:");
        book.setCity(view.getData());
        view.sendMessage("Enter name of publishing house, where book was published:");
        book.setPublishingHouse(view.getData());
        view.sendMessage("Enter year, when book was published:");
        book.setYear(view.getData());
        view.sendMessage("Enter count pages of a book:");
        book.setPages(view.getData());
        view.sendMessage("Save changes?");
        view.sendMessage("1.Yes");
        view.sendMessage("2.No");
        while(!correctData){
            switch(view.getData()){
                case "1": 
                    saveChanges=true; 
                    correctData=true;
                    break;
                case "2": 
                    saveChanges=false; 
                    correctData=true;
                    break;
                default: 
                    view.sendMessage("Entry data is incorrect. Try again");
                    correctData=false;
                    break;
            }
        }
        return saveChanges;
    }
И снова выходит ТТУК. Я, конечно, могу метод addBookInLibrary (и другие) перенести в bookManager, но получается, что bookManager, теперь должен будет знать о вьювере(чтобы посылать пользователю сообщения и забирать введенные им данные).
Но насколько я знаю, следуя шаблону MVC, представление и модель не должны знать друг о друге, контроллер должен жонглировать открытыми методами модели и представления.
И вот получается либо ТТУК, либо совсем не MVC, ну и третий (наиболее вероятный) вариант, что я что-то делаю не правильно, и есть выход из этого положения.
Подскажите, пожалуйста, как поступают в подобных ситуациях. Заранее спасибо!
0
Shamil1
Модератор
1822 / 1185 / 225
Регистрация: 26.03.2015
Сообщений: 4,362
02.03.2017, 18:45 #10
case "2":
Нужно сделать перечисление (enum).

Цитата Сообщение от es_ Посмотреть сообщение
Book book = new Book();
if(addBookInLibrary(book)){
CreateBookModel viewModel = new CreateBookModel() { /*инициализация */ };
CreateBookForm form = view.getBookData(viewModel);
if(form.saveChanges)
{
Book book = map(form);
Errors[] errors = _bookManager.addBookInLibrary(book);
if(errors != null)
{
// сообщаем об ошибках и даём продолжить создание книги
continue;
}
// книга успешно создана
continue;
}
// пользователь отказался от сохранения изменений
continue;

Всю информацию от пользователя собирает Представление. В частности view решает, какие вопросы, в каком порядке, на каком языке, каким шрифтом... и так далее... задавать пользователю.

Мы передаём в Представление всю информацию, которая требуется. Кроме информации о текущих значениях полей книги может быть и другая: сообщение об ошибках валидации, список издательств, чтобы пользователь мог выбрать, а не вводить, ... и так далее. (Возможен вариант, что Представление запрашивает список издательств у соответствующей service/manager самостоятельно).

Мы получаем из Представления заполненную Форму. Кроме полей книги она может содержать и другую информацию: выбор пользователя (нажатая кнопка), капча, ... и так далее.
Поля книги в форме обычно имеют более общий формат (строки). Например, пользователь мог ввести "2017-15-15" в поле "Дата Издания". Это значение надо запомнить и вернуть для исправления (а не предлагать пустое поле для ввода).

_bookManager обязательно валидирует перед сохранением (бизнес-логика не доверяет контроллеру) и может вернуть список ошибок.


з.ы. Решили отказаться от слоя со службами (IClientLibraryService)? В простых случаях можно, а в сложных не советую. Бизнес-логика может содержать десятки-сотни разных сущностей и Манагеров к ним. Зачем контроллеру знать их все по именам? И зачем контроллеру знать, в каком порядке их вызывать?
1
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
03.03.2017, 10:10  [ТС] #11
Спасибо за ответ! Прочитав все Ваши сообщения в посте, хотелось бы поступить следующим образом:
я опишу процесс добавления книги в библиотеку, как я его вижу, а Вы меня поправите, если я пойду не по оптимальному пути.
Если, конечно, Вас не затруднит.
Итак, как я вижу процесс добавления книги в библиотеку:
При запуске приложения в майне проинициализировали объекты нужных нам классов, у меня пока это выглядит так:
Java
1
2
3
4
5
public static void main(String[] args){
    TestBookRepository testBookRepository = new TestBookRepository();
    BookManager bookManager = new BookManager(testBookRepository);
    new Controller(bookManager);
}
Контроллер вызывает метод Представления, который выдает меню выбора действий пользователю, допустим, пользователь выбрал подменю добавления книги в библиотеку,
метод Представления возвращает значение, вызванного подменю Контроллеру.
Контроллер на основе полученного значения, вызывает нужное подменю из Представления и ждет от этого метода возвращения массива данных (List).
Метод Представления задает нужные вопросы пользователю, получает ответы, ответы забивает в массив данных и по завершению возвращает его Контроллеру.
Контроллер вызывает метод БукМенеджера (addBookInLibrary) и в параметрах передает полученный ранее массив данных от Представления.
БукМенеджер валидирует данные, если всё ок, то при помощи интерфейса IBookRepository отправляет данные на добавление их в БД или в тестовое хранилище.
Возвращаемое значение метода валидации есть массив ошибок, который получает Контроллер.
Контроллер просто пересылает этот массив в какой-нибудь метод Представления (создам метод для обработки массива ошибок).
Если массив пуст, то Представление пишет, что всё ок, если же не пуст, то выводит эти ошибки.

Вот как то так я это вижу. Спасибо за то, что тратите своё драгоценное время на растолкование всех этих механизмов взаимодействия системы!

з.ы. Нет, не отказался, пока хотелось бы понять механизм взаимодействия Модель-Вьювер-Контроллер.
Как окончательно разберусь, обязательно добавлю дополнительные улучшающие жизнь слои. Для меня так будет проще.
0
Shamil1
Модератор
1822 / 1185 / 225
Регистрация: 26.03.2015
Сообщений: 4,362
03.03.2017, 12:05 #12
Цитата Сообщение от es_ Посмотреть сообщение
Контроллер вызывает метод БукМенеджера (addBookInLibrary) и в параметрах передает полученный ранее массив данных от Представления.
Контроллер преобразует данные из формата, в котором они приходят из Представления, в формат, который принимает БукМенеджер. "Всё ок" или нет - решает Контроллер, а не Представление.

Цитата Сообщение от es_ Посмотреть сообщение
Контроллер просто пересылает этот массив в какой-нибудь метод Представления (создам метод для обработки массива ошибок).
Если массив пуст, то Представление пишет, что всё ок, если же не пуст, то выводит эти ошибки.
Контроллер анализирует список ошибок и принимает решение, что делать дальше.
Кликните здесь для просмотра всего текста
Например, Контроллер получил данные со страницы редактирования книги, преобразовал в нужный формат, вызвал метод бизнес-логики.
Если метод вернул ошибку, то лучшим решением выглядит опять отобразить страницу редактирования книги, передав туда список ошибок для отображения. При этом контроллер может, например, заменить текст сообщений об ошибках на более простой и понятный пользователю и т.п. (Например, одна и та же ошибка может выводиться по-разному читателю и библиотекарю).
Если метод отработал без ошибок, то лучшим решением выглядит перейти на страницу "книга добавлена" либо к списку книг либо к начальному меню.


Цитата Сообщение от es_ Посмотреть сообщение
Возвращаемое значение метода валидации есть массив ошибок, который получает Контроллер.
Можно так. А можно, например, передавать в метод коллекцию, в которую тот будет добавлять ошибки. Суть та же, но интерфейс взаимодействия делайте таким, как Вам удобней.
Только это не метод не метод для валидации, а метод для создания книги. Валидация - один из этапов процесса создания. Метод может вернуть ошибку типа "сервер бд недоступен" и т.п., а не только ошибки валидации.
1
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
03.03.2017, 13:08  [ТС] #13
Спасибо! Буду дорабатывать!
0
iSmokeJC
281 / 248 / 84
Регистрация: 21.10.2017
Сообщений: 865
25.01.2018, 22:46 #14
es_, уважаемый, я понимаю, что много времени прошло, но не завалялся исходник того, что у тебя получилось? Буду весьма признателен, если выложишь или скинешь на мыло.
Если есть подобные проекты, тоже можно. Точнее нужно. Пытаюсь вникнуть в грамотное ООП, но тотальный нехват поучительных исходников - или примитив, или что-то навороченное.
Обращаюсь не только к ТС, но и ко всем, кто владеет данной инфой, исходниками, ссылками.
Заранее спасибо!
0
es_
206 / 206 / 46
Регистрация: 14.01.2013
Сообщений: 456
29.01.2018, 09:36  [ТС] #15
Цитата Сообщение от es_ Посмотреть сообщение
Library.rar (9.6 Кб, 3 просмотров)
Привет, вот на одной из стадий разработки проекта, исходники выкладывал прямо здесь. Исходников по финальной доработке, к сожалению, не осталось. Но можно доработать имеющиеся, следуя комментариям из текущей темы
1
Вложения
Тип файла: rar Library.rar (9.6 Кб, 3 просмотров)
29.01.2018, 09:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.01.2018, 09:36
Привет! Вот еще темы с ответами:

паттерн наблюдатель (observer) - ООП и паттерны
Помогите разобраться. Нашел в интернете несколько примеров но по ним я не могу понять как они работают, приведите пример. Если есть пример...

Как называется паттерн? - ООП и паттерны
здравствуйте, в общем начитался тут всякого: http://mariusbancila.ro/blog/2014/10/15/extension-methods-in-cpp/ сам раньше кодил...

Паттерн Фасад (Facade) - ООП и паттерны
Всем привет ! Необходимо реализовать паттерн Фасад. Есть классы, наследующие разные элементы (Кнопки, панели, текстовые поля и т.д.) :...

Выбрать паттерн проектирования - ООП и паттерны
Есть вот такое задание: &quot;Разработать программное приложение, позволяющее проводить анализ алгоритмов нахождения обратных матриц....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru