Task 22 — Паттерны проектирования
Factory, Abstract Factory и MVC в прикладных задачах.
Edit on GitHubЗадание
Factory, Abstract Factory и MVC в прикладных задачах. Документация собрана по исходному коду этой практики.
Решение
Полный код решения по этой практике:
Исходные файлы решения
Task22/one/Complex.javaTask22/one/ComplexAbstractFactory.javaTask22/one/ConcreteFactory.javaTask22/one/TestComplex.javaTask22/three/CarcasController.javaTask22/three/CarcasModel.javaTask22/three/CarcasView.javaTask22/three/CreateTextDoc.javaTask22/three/ICreateDocument.javaTask22/three/IDocument.javaTask22/three/TestWindow.javaTask22/three/TextDocument.javaTask22/two/AbstractChairFactory.javaTask22/two/Chair.javaTask22/two/ChairFactory.javaTask22/two/Client.javaTask22/two/FunctionalChair.javaTask22/two/MagicChair.javaTask22/two/TestChair.javaTask22/two/VictorianChair.java
Task22/one/Complex.java
package Task22.one;
public class Complex {
private int real;
private int image;
public Complex(){
this.real=0;
this.image=0;
}
public Complex(int real, int image) {
this.real=real;
this.image=image;
}
public int getReal() {
return real;
}
public void setReal(int real) {
this.real = real;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
@Override
public String toString() {
return "Комплексное число = "+ real +
" + " + image + "i";
}
}
Task22/one/ComplexAbstractFactory.java
package Task22.one;
public interface ComplexAbstractFactory {
Complex createComplex();
Complex CreateComplex(int real, int image);
}
Task22/one/ConcreteFactory.java
package Task22.one;
public class ConcreteFactory implements ComplexAbstractFactory {
@Override
public Complex createComplex() {
return new Complex();
}
@Override
public Complex CreateComplex(int real, int image) {
return new Complex(real, image);
}
}
Task22/one/TestComplex.java
package Task22.one;
public class TestComplex {
public static void main(String[] args){
ComplexAbstractFactory c = new ConcreteFactory();
System.out.println(c.CreateComplex(1,7));
System.out.println(c.createComplex());
}
}
Task22/three/CarcasController.java
package Task22.three;
import javax.swing.*;
import java.io.FileNotFoundException;
import java.io.IOException;
public class CarcasController {
private final CarcasModel model;
private final CarcasView view;
public CarcasController() {
this.model = new CarcasModel();
this.view = new CarcasView<>();
view.addNewListener(e -> {
model.setDocument(new CreateTextDoc().CreateNew());
view.showDocText((TextDocument) model.getDocument());
});
view.addOpenListener(e -> {
try {
model.setDocument(new CreateTextDoc().CreateOpen(((CarcasView.openDocA) e).getPath()));
view.showDocText((TextDocument) model.getDocument());
} catch (FileNotFoundException exc) {
JOptionPane.showMessageDialog(view, "File does not exist");
}
});
view.addSaveListener(e -> {
var document = ((CarcasView.saveDocA)e).getDocument();
System.out.println("Saved");
try {
document.save();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
}
void showWindow() {
this.view.setVisible(true);
}
}
Task22/three/CarcasModel.java
package Task22.three;
public class CarcasModel {
private IDocument<?> document;
public CarcasModel() {
}
public CarcasModel(IDocument<?> document) {
this.document = document;
}
public IDocument<?> getDocument() {
return document;
}
public void setDocument(IDocument<?> document) {
this.document = document;
}
}
Task22/three/CarcasView.java
package Task22.three;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
public class CarcasView<T> extends JFrame {
IDocument<T> doc;
class newDocA extends ActionEvent {
public newDocA(Object obj) {
super(obj, 0, "");
}
}
class openDocA extends ActionEvent {
private String path;
public String getPath() {
return path;
}
public openDocA(Object source, String path) {
super(source, 0, "");
this.path = path;
}
}
JMenuBar menu = new JMenuBar();
ArrayList<ActionListener> saveListener = new ArrayList<>();
ArrayList<ActionListener> newListener = new ArrayList<>();
ArrayList<ActionListener> openListener = new ArrayList<>();
class saveDocA extends ActionEvent {
private IDocument<T> doc;
public saveDocA(Object obj, IDocument<T> doc) {
super(obj, 0, "");
this.doc = doc;
}
public IDocument<T> getDocument() {
return doc;
}
}
void addNewListener(ActionListener actionListener) {
newListener.add(actionListener);
}
void addOpenListener(ActionListener actionListener) {
openListener.add(actionListener);
}
void addSaveListener(ActionListener actionListener) {
saveListener.add(actionListener);
}
void setOpenDoc(String path) {
for (ActionListener actionListener: openListener) {
actionListener.actionPerformed(new openDocA(this, path));
}
}
void setNewDoc() {
for (ActionListener actionListener: newListener) {
actionListener.actionPerformed(new newDocA(this));
}
}
void setSaveDoc() {
for (ActionListener actionListener: saveListener) {
actionListener.actionPerformed(new saveDocA(this, doc));
}
}
CarcasView() {
setTitle("Каркас");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 200);
JMenu fileItem = new JMenu("Файл");
JMenuItem newPosition = new JMenuItem("Создать");
newPosition.addActionListener(e -> {
setNewDoc();
});
JMenuItem openPosition = new JMenuItem("Открыть");
openPosition.addActionListener(e -> {
JFileChooser file_choose = new JFileChooser();
if (file_choose.showDialog(getContentPane(), "OK") == JFileChooser.APPROVE_OPTION) {
setOpenDoc(file_choose.getSelectedFile().getAbsolutePath());
}
});
JMenuItem savePosition = new JMenuItem("Сохранить");
savePosition.addActionListener(e -> {
setSaveDoc();
});
JMenuItem exitPosition = new JMenuItem("Выход");
exitPosition.addActionListener(e -> {
setVisible(false);
});
fileItem.add(newPosition);
fileItem.add(openPosition);
fileItem.add(savePosition);
fileItem.add(exitPosition);
menu.add(fileItem);
setJMenuBar(menu);
setBounds(0, 0, 390, 200);
}
void showDocText(TextDocument textDocument) {
this.doc = (IDocument<T>) textDocument;
setTitle("Текущий документ - " + textDocument.getName());
getContentPane().removeAll();
repaint();
JTextArea textFieldBig = new JTextArea(textDocument.getContent());
textFieldBig.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent documentEvent) {
((TextDocument)doc).setContent(textFieldBig.getText());
}
@Override
public void removeUpdate(DocumentEvent documentEvent) {
((TextDocument)doc).setContent(textFieldBig.getText());
}
@Override
public void changedUpdate(DocumentEvent documentEvent) {
((TextDocument)doc).setContent(textFieldBig.getText());
}
});
add(textFieldBig);
setBounds(0, 0, 450, 200);
}
}
Task22/three/CreateTextDoc.java
package Task22.three;
import java.io.*;
import java.util.stream.Collectors;
public class CreateTextDoc<T> implements ICreateDocument{
public IDocument<T> CreateNew() {
return (IDocument<T>) new TextDocument("Безымянный");
}
@Override
public IDocument<T> CreateOpen(String path) throws FileNotFoundException {
BufferedReader file = new BufferedReader(new FileReader(path));
return (IDocument<T>) new TextDocument(path, file.lines().collect(Collectors.joining("\n")));
}
}
Task22/three/ICreateDocument.java
package Task22.three;
import java.io.*;
public interface ICreateDocument <T>{
IDocument<T> CreateNew();
IDocument<T> CreateOpen(String path) throws FileNotFoundException;
}
Task22/three/IDocument.java
package Task22.three;
import java.io.IOException;
public interface IDocument <T>{
String getName();
void setName(String name);
String getContent();
void setContent(String content);
void save() throws IOException;
}
Task22/three/TestWindow.java
package Task22.three;
import javax.swing.*;
public class TestWindow {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ignored){}
CarcasController controller = new CarcasController();
controller.showWindow();
}
}
Task22/three/TextDocument.java
package Task22.three;
import java.io.*;
public class TextDocument implements IDocument{
private String text;
private String name;
TextDocument(String name) {
this.name = name;
}
TextDocument(String name, String text) {
this.name = name;
this.text = text;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getContent() {
return text;
}
@Override
public void setContent(String text) {
this.text = text;
}
@Override
public void save() throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(name));
writer.write(text);
writer.close();
}
}
Task22/two/AbstractChairFactory.java
package Task22.two;
public interface AbstractChairFactory {
VictorianChair createVictorianChair();
MagicChair createMagicanChair();
FunctionalChair createFunctionalChair();
}
Task22/two/Chair.java
package Task22.two;
public interface Chair {
}
Task22/two/ChairFactory.java
package Task22.two;
public class ChairFactory implements AbstractChairFactory {
@Override
public VictorianChair createVictorianChair() {
return new VictorianChair(35);
}
@Override
public MagicChair createMagicanChair() {
return new MagicChair();
}
@Override
public FunctionalChair createFunctionalChair() {
return new FunctionalChair();
}
}
Task22/two/Client.java
package Task22.two;
import Task22.two.Chair;
public class Client implements Chair {
Chair chair;
public void sit(){
System.out.println("Клиент сел на стул.");
}
public void setChair(Chair chair){
this.chair=chair;
}
}
Task22/two/FunctionalChair.java
package Task22.two;
public class FunctionalChair implements Chair {
public int sum(int a, int b){
return a+b;
}
}
Task22/two/MagicChair.java
package Task22.two;
public class MagicChair implements Chair {
public void doMagic(){
System.out.println("Магический стул");
}
}
Task22/two/TestChair.java
package Task22.two;
import java.util.Scanner;
public class TestChair {
public static void main(String[] args){
AbstractChairFactory af = new ChairFactory();
Scanner s = new Scanner(System.in);
Client c = new Client();
System.out.println("Введите 1если нужен старинный стул, 2если нужен магический стул, 3если нужен функциональный стул.");
int a = s.nextInt();
if (a ==1){
VictorianChair v = af.createVictorianChair();
System.out.println(v.getAge()+" лет");
}
if (a ==2){
MagicChair m = af.createMagicanChair();
m.doMagic();
}
if (a==3){
FunctionalChair f = af.createFunctionalChair();
System.out.println("Сумма = "+f.sum(39,12));
}
if (a==1||a==2||a==3){
c.sit();
}else{
System.out.println("В каталоге нет такого вида стульев");
}
}
}
Task22/two/VictorianChair.java
package Task22.two;
public class VictorianChair implements Chair {
private int age;
public VictorianChair(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
Описание
В этом модуле используется 20 Java-файлов. Ключевые сущности: Complex, ComplexAbstractFactory, ConcreteFactory, TestComplex, CarcasController, CarcasModel.
tip
Для проверки практики сначала запускайте тестовый/демо-класс из папки задачи, затем расширяйте модель новыми кейсами.
Вывод
Task 22 — Паттерны проектирования документирует реальное решение из исходного кода.