Глядя на YouTube и Google, я создал код для простой панели Jpanel с кнопкой, однако то, что не говорят мне видео, — это какие шаблоны дизайна я использую

#java #design-patterns

Вопрос:

Я создал приложение, которое позволяет создавать экземпляры фигур, которые могут быть кругом, прямоугольником или чем угодно, и использовал метод сортировки (Пузырьковая сортировка) для сортировки шести фигур на основе интерфейсов.

Проблема в том, что я не знаком с шаблонами дизайна и с тем, какие шаблоны используются — я новичок, поэтому я следил за видео на YouTube и играл с ними, и это сработало.

У меня есть 1 основной класс, где у меня есть ОСНОВНОЙ :

 public class Main {
public static void main(String[] args) {
    JButton btnLoadShapes, btnSortShapes;
    
    btnLoadShapes = new JButton("Load Shapes");
    btnLoadShapes.setBounds(150, 10, 150, 30);
    
    btnSortShapes = new JButton("Sort Shapes");
    btnSortShapes.setBounds(310, 10, 150, 30);
    
    
    JPanel panelShapes = new JPanel() {
        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            
            Shape shape = new Shape();
            g2d.setColor(Color.RED);
            Square s = shape.getS();
        
            g2d.fillRect(s.getX(),s.getY(),s.getWidth(), s.getHeight());
        
            
            g2d.setColor(Color.BLUE);
            Circle c = shape.getC();
            g2d.fillOval(c.getX(),c.getY(), c.getWidth(), c.getHeight());
            
            g2d.setColor(new Color(131, 21, 1));
            Rectangle r = shape.getR();
            g2d.fillRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
            
            g2d.setColor(Color.PINK);
            Circle C1 = shape.getC1();
            g2d.fillOval(C1.getX(),C1.getY(), C1.getWidth(), C1.getHeight());
            
            g2d.setColor(Color.green);
            Square S1 = shape.getS1();
            g2d.fillRect(S1.getX(),S1.getY(),S1.getWidth(), S1.getHeight());
            
            g2d.setColor(Color.magenta);
            Rectangle r2 = shape.getR2();
            g2d.fillRect(r2.getX(),r2.getY(),r2.getWidth(), r2.getHeight());
            
            
            
            
            
        } 

    };
    
    panelShapes.setBounds(10, 50, 560, 500);
    panelShapes.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    panelShapes.setVisible(false);
    
    btnLoadShapes.addActionListener(new ActionListener() {
        
        @Override
        public void actionPerformed(ActionEvent e) {
            panelShapes.setVisible(true);
        }
    });
 

и я создал 3 разных класса: Круг, прямоугольник и Квадрат, из которых я вызываю rectangle = shape.getC();
Например
, круг публичных занятий {
частное int x, y, ширина, высота;

 public Circle(int x, int y, int width, int height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

public int getX() {
    return x;
}

public void setX(int x) {
    this.x = x;
}

public int getY() {
    return y;
}

public void setY(int y) {
    this.y = y;
}

public int getWidth() {
    return width;
}

public void setWidth(int width) {
    this.width = width;
}

public int getHeight() {
    return height;
}

public void setHeight(int height) {
    this.height = height;
}
 

}

Теперь, наконец, я создал еще 2 класса под названием «Форма и сортировка», где в форме я ввел общедоступную форму s = новый квадрат с размерами и заданными получателями и установщиками, и, наконец, я использовал технику сортировки.

Может ли кто-нибудь помочь мне понять, какие шаблоны проектирования здесь используются? ( Я предполагаю, что используется фабричный метод = так как я определил main (* интерфейс) и создал подклассы ( Фигуры прямоугольник круг) для создания экземпляра.

Извините, если я звучу неуместно — я просто пытаюсь понять и изучить это.

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

1. Код вырван из контекста, но, основываясь на public class Circle { том , что я бы не сказал, что вы используете фактический шаблон «фабрики», поскольку «фабрика» вернет базовое представление, детали реализации не имеют значения. Как a Car , но фабрика могла бы производить a Ford или Tesla , но они все еще являются примером Car

2. Я обновил коды, дайте мне знать, если это поможет

3. Кажется очень странным писать какой-то код и предполагать, что это шаблон. Во-первых, вам не нужно использовать какой-либо шаблон для написания кода. Во-вторых, если вы хотите узнать о шаблонах, то почему бы не изучить шаблоны? Существует множество книг, видео, блогов и т. Д. где вам не нужно гадать. В-третьих, шаблоны не являются хорошим способом изучения программирования, ИМО. Они не являются темой для начинающих/вводной. Знание того, как кодировать без шаблонов, более ценно, чем знание шаблонов. Паттерны вторичны.

Ответ №1:

«Фабрика» создает «что-то», в этом контексте важно то, что вам все равно, «как» оно создано, только то, что оно соответствует указанному типу.

Например, у вас есть ShapeFactory устройство, которое может создавать различные формы, вам все равно, «как» эти формы определены или реализованы, только то, что они соответствуют понятию «форма».

Итак, давайте начнем с базовой концепции…

 public interface Shape {
    public void paint(Graphics2D g2d);
}
 

Это просто определяет базовую концепцию и утверждает, что ее можно нарисовать.

Далее, нам нужно что-то для создания этих фигур…

 public class ShapeFactory {
    
    enum ShapeType {
        CIRCLE, RECTANGE, SQUARE;
    }
    
    public static Shape create(ShapeType type, int x, int y, int width, int height, Color storkeColor, Color fillColor) {
        return null;
    }
    
}
 

Ладно, в нынешнем виде это довольно скучно, он вернется только null сейчас, но это дает нам базовый контракт.

«Пожалуйста, фабрика, создайте мне фигуру указанного типа, в указанных пределах, с указанными цветами»

Теперь, как я уже сказал, реализация не имеет значения для вызывающего, и у нас может быть динамическая фабрика, которая может делегировать создание другим фабрикам, которые могут создавать формы по-разному в зависимости от широкого набора потребностей … но это забегая вперед.

Давайте займемся созданием некоторых реальных фигур…

 public abstract class AbstractShape implements Shape {

    private int x;
    private int y;
    private int width;
    private int height;
    
    private Color storkeColor;
    private Color fillColor;

    public AbstractShape(Color storkeColor, Color fillColor) {
        this.storkeColor = storkeColor;
        this.fillColor = fillColor;
    }

    public AbstractShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
        this(storkeColor, fillColor);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    protected void setX(int x) {
        this.x = x;
    }

    protected void setY(int y) {
        this.y = y;
    }

    protected void setWidth(int width) {
        this.width = width;
    }

    protected void setHeight(int height) {
        this.height = height;
    }

    public Color getStorkeColor() {
        return storkeColor;
    }

    public Color getFillColor() {
        return fillColor;
    }

    @Override
    public void paint(Graphics2D g2d) {
        Graphics2D g = (Graphics2D) g2d.create();
        Color storkeColor = getStorkeColor();
        Color fillColor = getFillColor();
        
        if (fillColor != null) {
            g.setColor(fillColor);
            paintFilled(g);
        }
        
        if (storkeColor != null) {
            g.setColor(storkeColor);
            paintStroked(g);
        }
        g.dispose();
    }
    
    abstract protected void paintFilled(Graphics2D g2d);
    abstract protected void paintStroked(Graphics2D g2d);
    
}

public class CircleShape extends AbstractShape {

    public CircleShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
        super(storkeColor, fillColor);
        int size = Math.min(width, height);
        x = x   ((width - size) / 2);
        y = y   ((height - size) / 2);
        
        setX(x);
        setY(y);
        setWidth(size);
        setHeight(size);
    }

    @Override
    protected void paintFilled(Graphics2D g2d) {
        g2d.fillOval(getX(), getY(), getWidth(), getHeight());
    }

    @Override
    protected void paintStroked(Graphics2D g2d) {
        g2d.drawOval(getX(), getY(), getWidth(), getHeight());
    }
    
}
       
public class SquareShape extends AbstractShape {

    public SquareShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
        super(storkeColor, fillColor);
        int size = Math.min(width, height);
        x = x   ((width - size) / 2);
        y = y   ((height - size) / 2);
        
        setX(x);
        setY(y);
        setWidth(size);
        setHeight(size);
    }

    @Override
    protected void paintFilled(Graphics2D g2d) {
        g2d.fillRect(getX(), getY(), getWidth(), getHeight());
    }

    @Override
    protected void paintStroked(Graphics2D g2d) {
        g2d.drawRect(getX(), getY(), getWidth(), getHeight());
    }
    
}
       
public class RectagleShape extends AbstractShape {

    public RectagleShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
        super(x, y, width, height, storkeColor, fillColor);
    }

    @Override
    protected void paintFilled(Graphics2D g2d) {
        g2d.fillRect(getX(), getY(), getWidth(), getHeight());
    }

    @Override
    protected void paintStroked(Graphics2D g2d) {
        g2d.drawRect(getX(), getY(), getWidth(), getHeight());
    }
    
}
 

Мне всегда нравится abstract , когда класс несет в себе «общую» функциональность и помогает немного упростить жизнь.

Здесь важно отметить , что оба CircleShape и SquareShape , по своей природе, ну, квадратные (они имеют одинаковую ширину и высоту). Итак, в этой реализации я определяю их так, чтобы они укладывались в середину указанных границ — это деталь «реализации».

«Но разве не это я делаю для тебя?» ты спрашиваешь. Ну, нет, не совсем так. Например , когда вы вызываете shape.getS() , он возвращает конкретный класс, который, как я предполагаю, обладает теми же свойствами, что и последний созданный им объект, в противном случае он будет перемещаться повсюду.

Вместо этого я позволяю вам определить свойства, которые вы хотите, чтобы форма имела, а затем создать ее.

Хочешь торт? Конечно, передайте мне ингредиенты, и я приготовлю вам торт, вы все равно получите торт, но в зависимости от ингредиентов это другой «тип» торта.

Итак, основываясь на вышесказанном, мы могли бы сделать что-то вроде…

Вся ваша форма принадлежит нам

 public class TestPane extends JPanel {
    
    private List<Shape> shapes = new ArrayList<>(25);
    
    public TestPane() {
        shapes.add(ShapeFactory.create(ShapeFactory.ShapeType.CIRCLE, 10, 10, 200, 100, Color.RED, Color.BLUE));
        shapes.add(ShapeFactory.create(ShapeFactory.ShapeType.RECTANGE, 10, 120, 200, 100, Color.BLUE, Color.GREEN));
        shapes.add(ShapeFactory.create(ShapeFactory.ShapeType.SQUARE, 10, 240, 200, 100, Color.GREEN, Color.YELLOW));
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(220, 350);
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        for (Shape shape : shapes) {
            shape.paint(g2d);
        }
        g2d.dispose();
    }
    
}
 

Я мог бы сделать ShapeFactory это с помощью преданных createCircle createRectangle и createSquare методов , я мог бы вернуть их interfaces Circle , Square и Rectangle (и я бы основал их , Shape потому что я такой), и это все равно было бы фабрикой.

Одна из вещей, которую следует иметь в виду, заключается в том, что «фабрика» должна быть независимой от реализации. Я должен был бы использовать фабрики «разных» форм для получения разных эффектов, но в конце концов они все равно будут генерировать Shape s

Помните, фабрика возьмет что-то и создаст что-то из этого.