Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #14620 > unrolled thread

Re: How is this "pattern" called?

Started bymarkspace <-@.>
First post2012-05-18 08:29 -0700
Last post2012-05-19 22:29 -0400
Articles 6 — 4 participants

Back to article view | Back to comp.lang.java.programmer

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: How is this "pattern" called? markspace <-@.> - 2012-05-18 08:29 -0700
    Re: How is this "pattern" called? markspace <-@.> - 2012-05-18 08:37 -0700
    Re: How is this "pattern" called? markspace <-@.> - 2012-05-18 10:35 -0700
      Re: How is this "pattern" called? Wanja Gayk <brixomatic@yahoo.com> - 2012-05-30 14:32 +0200
    Re: How is this "pattern" called? "John B. Matthews" <nospam@nospam.invalid> - 2012-05-18 15:35 -0400
    Re: How is this "pattern" called? Arne Vajhøj <arne@vajhoej.dk> - 2012-05-19 22:29 -0400

#14620 — Re: How is this "pattern" called?

Frommarkspace <-@.>
Date2012-05-18 08:29 -0700
SubjectRe: How is this "pattern" called?
Message-ID<jp5ptm$jp9$1@dont-email.me>
On 5/18/2012 1:53 AM, Stefan Ram wrote:
>    In the MVC pattern, I think, M, V, and C should be at least
>    one non-innner class each?
>
>    I often have seen (possibly, especially in beginner code) a
>    coding pattern, where there is only one single non-inner class:
>    the model.


"Especially in beginner code" seems to say to me that they might be 
copying from beginner examples, especially of the sort that appear in 
Oracle's Java tutorial.  These example are designed to be shorter to 
read on a web page or book page, and don't show best practice or correct 
pattern.  The examples simply show how to use the API.

Also, MVC is not MVC.  That is, most languages and frameworks use a 
modified MVC that really isn't MVC.  Java itself uses a "split model" 
design pattern.  Model-Presenter-Controller is currently a popular 
design pattern which can be used in Java.

<http://www.martinfowler.com/eaaDev/uiArchs.html>


>
>    The listeners and the view then are embedded into this
>    model, possibly, as inner classes. It's not really MVC
>    as the observer pattern is not used for decoupling.


"Close coupling" is an anti-pattern in most cases.

Do you have an example we could look at?

[toc] | [next] | [standalone]


#14621

Frommarkspace <-@.>
Date2012-05-18 08:37 -0700
Message-ID<jp5qc2$n26$1@dont-email.me>
In reply to#14620
On 5/18/2012 8:29 AM, markspace wrote:
> design pattern. Model-Presenter-Controller is currently a popular design


Argh.  Model-View-Presenter.  How did I mix those up?

[toc] | [prev] | [next] | [standalone]


#14624

Frommarkspace <-@.>
Date2012-05-18 10:35 -0700
Message-ID<jp619l$5ms$1@dont-email.me>
In reply to#14620
On 5/18/2012 9:59 AM, Stefan Ram wrote:

>    I do not see a real problem with this style, assuming that
>    the assignment at hand was just to write such a simple dot
>    paint program.


Right, though the style doesn't particularly teach best practice either.

I think I'd call this the "monolithic example" pattern.  It's similar to 
a lot of example code I see in books and the Java tutorial.  It's 
monolithic because it crams everything into a single class, or at least 
into the minimum page space.

And it's an example because that's what it is.  A short program that 
isn't written by more than one person, and will not be maintained.  It's 
fine for what it is, but it's not an example of good production style 
coding either.

[toc] | [prev] | [next] | [standalone]


#14935

FromWanja Gayk <brixomatic@yahoo.com>
Date2012-05-30 14:32 +0200
Message-ID<MPG.2a30200c52428337989702@202.177.16.121>
In reply to#14624
In article <jp619l$5ms$1@dont-email.me>, -@. says...

> Right, though the style doesn't particularly teach best practice 
> either.
> 
> I think I'd call this the "monolithic example" pattern.

That pattern is known as "god class".

>  It's similar to 
> a lot of example code I see in books and the Java tutorial.  It's 
> monolithic because it crams everything into a single class, or at least 
> into the minimum page space.
> 
> And it's an example because that's what it is.  A short program that 
> isn't written by more than one person, and will not be maintained.  It's 
> fine for what it is, but it's not an example of good production style 
> coding either.

As a Java/Swing developper with almost a decade of experience, having 
seen a lot of code that got refactored inside out and back again, It's 
not that simple to say sonmething is good or bad. It depends on the 
purpose.

For the start it's a pragmatic, yet entirely easy to refactor approach 
that has one goal in mind: Keep a unit/module together. 
I do agree that you should tear this apart into several classes, but to 
understand why, let me start to develop the idea.

It all starts with one decision: Will we ever exchange view technology 
(like Swing to SWT)? You can't know, so you should be flexible, right? 
Wrong! I have yet to see one big project, huge as a retail system, 
migrate from one view technology to the other. People don't do it, it's 
massively expensive and they rather pay to keep the old technology alive 
and patched than to migrate to a new one. So don't expect insurance 
companies and warehouse chains to migrate a huge in house application 
from Swing to SWT, JavaFX 2.0 or a web interface anytime soon. Things 
are that complex and there are so many framework specific hacks involved 
that migrating is a daunting task that only very few companies are 
willing to pay for. Usually there have been a lot of developers on the 
project, some of them good, some of them rather bad, you will dig out 
big piles of code that hurts your eyes (and your code will hurt theirs) 
and you'll have to untangle some huge mess before you can even start to 
think about that. Don't do it.
Do we need flexibility here? Rather not.

It needs a very good framework to separate the concerns good enough to 
ease the pain (I'm glad I had the opportunity to work on one as 
framework-developper and user) of switching from Swing to SWT alone, 
still it is a heavy task. Basically that framework has to have an own 
abstraction for every widget that talks to the original Swing-Widget, 
Abstractions for teh EventQueue and so on, so the GUI technology can be 
replaced rather easily. Most smaller businesses don't have that, they 
simply can't afford to build and maintain a huge ass framework like 
that. So what they do is buy one. Then you'll have to stick to its rules 
anyway, which some developers wil happily ignore, which is where your 
problem will resurface. Forget it, quite frankly.

So here we are again: Average company, no special framework involved, 
time pressure is on, external developers going in and out all the time.
What you need is some kind of clear structure and everything should be 
easy to find. You don't want to spread one module (like the mask for 
editing an article) over a huge class hierarchy with too many small 
classes cluttering up your directories, so no one finds anything.

Now here's where it starts to get intersting, because you can approach 
it differently. Most of you will know the web developer world, but let 
me use a usual fat client example here, as this is what the example 
seemed to suggest.

What do you need in general?

* You have a view

* You have some business logic, some of that will reflect in the way the 
view behaves (no mail order -> mail service combobox not editable), some 
of that will not (posting an order takes something off the stock, puts 
it into the delivery queue and sends a confirmation email, whatever).

* You have validation, both for the view (name must be entered) and for 
the businsss logic (item is out of stock, another user just ordered it 
the second you klicked to send your order).

You need to glue that together, which is what the controller does, and 
you need to embed all this in some application frame.

So a pragmatic approach is to have a module class, say the "article 
module", which includes some value object for what's currently 
displayed/edited - and that's not necessarily what you need to give the 
widget: You like to validate and store a list, not a table model / you 
like to have some booleans, not a button model.
Now you need some view, a validation code block and some code to CRUD 
things in the database, if you need one.

To keep the module API small, it should not feature much more than 
necessary to incorporate the module in the application frame, 
initialize, display and tear it down again, everything else is "internal 
affairs".

Next decision: Do you want to use a GUI-Designer like JFormDesigner? 
Probably yes.
So you should have an own class for the widgets and their layout.

Now you don't want to access each field individually, so you would 
probably hand over a copy of the value object to the view, so it can do 
with it whatever it wants without affecting anything. You need to have 
some event handling to get to know that some thing has changed in the 
view that you might need to validate, do you?
Now you have the option to move some validation into the view, because 
it's its internal affair, but that could get you into problems with re-
generating a GUI class. And GUI-Designer code is usually huge and 
verbose and you don't want to edit that class manually and you don't 
want ot to hide and obscure code relevant for business. So you could 
keep it in the controller. For the same reason you possibly like to have 
the code for binding a widget to a property in the value object in the 
value object itself.

You have now split the module into two top level classes: A presenter 
and a view. The rest is inner classes.

You could be fine here, this is almost what you see above, only with 
some tweaking for use with a GUI designer tool.

Next decision: Do you want ORM-mapping for your persistence?
If so, you need an entity class. And you need some code that transfers 
your value object's data to the database. Or you use the entity itself 
as vaue object (which is a nice idea at first, but may fall on your feet 
later, especially when you encounter things like a manual undo).

So you have three top level classes: A presenter, a view and an entity.

Next decision: Do you want client/server separation and do you need some 
stiffer security?
This is an important decision, and for a huge business application it 
would be a clear yes most of the times. 
I've also seen a domain driven design, where you actually had business 
logic and validation in the entities itself, which also served as value 
objects for the view, so the client was doing all the business logic and 
the server was just a database with some client logon/logoff and 
permission stuff. Not what you would call hard to attack for anyone who 
gets access to the client, but certainly enough for in house use on an 
intranet in a small company and it was very clear where to find what.

If you want to separate client/server, you need some class to host the 
web services for that module on the server side. 
You will need to move some validation there - the stuff that is not 
directly reflected in the GUI. This is the point where you will repeat 
some of the validation from the GUI to be sure no one sends some weird 
data from a modified client. And you will need to push some business 
logic here, because sending mail for example, and changing the stock, is 
not anymore client's business.

So now you have four top level classes: Presenter, View, Web Service, 
Entity.
And you will have them in two different projects: 
A "server" project and a "client" project.

Now let's go and solve the DRY-Principle that you have violated when 
pushing the validation into the text field: 
Your view would check a number field to highlight a value out of bounds, 
your webservice would check it to throw an exception. 
There you can move your validation to a top level class and put it into 
a "common" project that is both included in the classpath of the client 
and server. Since the client and the server both have their own class 
loaders, you can't just simply modify the validator on the client side, 
the server would still see his version of the class, so that practice is 
safe enough to go with. You will need to move the business rules there 
too, because you need them for validation and you don't want to make a 
web service call everytime you change a combobox value in the view.
Be aware though, that this will violate the SOA (Service Oriented 
Architecture) that you have just established by introducing the web 
service. 

If you really need SOA at this point, you need to bite the bullet and 
either live with a lot of web service calls and kill your user 
experience with sluggish behavior or violate DRY.

Anyway, for your module you might have five top level classes now:
Presenter, View, Web Service, Validator, Entity.

This is not quite "model view controller", but still a reasonable 
architecture.

What do you think?

Kind regards,
-Wanja-

-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---

[toc] | [prev] | [next] | [standalone]


#14630

From"John B. Matthews" <nospam@nospam.invalid>
Date2012-05-18 15:35 -0400
Message-ID<nospam-0A319A.15355218052012@news.aioe.org>
In reply to#14620
In article <MVC-20120518183901@ram.dialup.fu-berlin.de>,
 ram@zedat.fu-berlin.de (Stefan Ram) wrote:

> I do not see a real problem with this style, assuming that the 
> assignment at hand was just to write such a simple dot paint program.
> 
> The inner classes can easily share a common model and identifier 
> scope, while at the same time there is some reasonable separation 
> between the different concerns of the inner classes.
> 
> Should it be required later to decouple one of these inner classes 
> more than now, this is also possible using a refactor that will make 
> it become an outer class or will introduce an observer relationship. 
> But should it not be required later, no time is wasted now to 
> implement a decoupling and separation not needed.

I sometimes strive to make nested classes static in order to facilitate 
re-factoring, as suggested in the example below. Static also keeps me 
honest on inadvertent coupling. I also use the somewhat dated Observer 
and Observable classes to stress the observer pattern, even implementing 
Observer despite leaking `this`.

Here's my understanding of the basic architecture:

<http://stackoverflow.com/a/2687871/230513>

Here's a more elaborate example that mentions other ways to implement 
the observer pattern:

<http://stackoverflow.com/a/3072979/230513>

And I frequently refer to this article on Swing & MVC

<http://java.sun.com/products/jfc/tsc/articles/architecture/>

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MVCMain {

    public static void main(String args[]) {
        new MVCMain().buildGui();
    }

    public void buildGui() {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                Model model = new Model();
                View view = new View(model);
                Control control = new Control(model, view);
                JFrame f = new JFrame();
                f.add(view);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }

    private static final class Model extends Observable {

        private List<Point> points = new ArrayList<Point>();

        public void next(Point p) {
            points.add(p);
            setChanged();
            notifyObservers();
        }

        public List<Point> getPoints() {
            return points;
        }
    }

    private static final class View extends JPanel implements Observer {

        private Model model;

        public View(Model model) {
            this.model = model;
            this.model.addObserver(this);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.blue);
            for (Point p : model.getPoints()) {
                g.fillRect(p.x, p.y, 8, 8);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }

        @Override
        public void update(Observable o, Object arg) {
            repaint();
        }
    }

    private static final class Control {

        private Model model;
        private View view;

        public Control(final Model model, View view) {
            this.model = model;
            this.view = view;
            this.view.addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    model.next(e.getPoint());
                }
            });
        }
    }
}

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

[toc] | [prev] | [next] | [standalone]


#14667

FromArne Vajhøj <arne@vajhoej.dk>
Date2012-05-19 22:29 -0400
Message-ID<4fb85727$0$295$14726298@news.sunsite.dk>
In reply to#14620
On 5/18/2012 12:59 PM, Stefan Ram wrote:
> final class Main
> {
>    /* model */
>
>    final private java.util.Collection<java.awt.Point>  collection
>     = new java.util.ArrayList<>();
>
>    /* view */
>
>    Panel panel;
>    final private class Panel extends javax.swing.JPanel
>    { public Panel()
>      { this.setPreferredSize( new java.awt.Dimension( 300, 300 ));
>        this.addMouseListener( new MouseListener() ); }
>      final @java.lang.Override public void paintComponent
>      ( final java.awt.Graphics graphics )
>      { super.paintComponent( graphics );
>        for( final java.awt.Point point : Main.this.collection )
>        graphics.fillRect( point.x, point.y, 4, 4 ); }}
>
>    final private class Frame extends javax.swing.JFrame
>    { Frame()
>      { Main.this.panel = new Panel(); this.add( Main.this.panel );
>        this.setDefaultCloseOperation
>        ( javax.swing.WindowConstants.DISPOSE_ON_CLOSE );
>        this.pack(); this.setVisible( true ); }
>      final @java.lang.Override public void dispose(){ super.dispose(); }}
>
>    /* controller */
>
>    final private class MouseListener extends java.awt.event.MouseAdapter
>    { public final void mousePressed
>      ( final java.awt.event.MouseEvent mouseEvent )
>      { Main.this.collection.add
>        ( new java.awt.Point( mouseEvent.getX(), mouseEvent.getY() ));
>        Main.this.panel.repaint(); }}
>
>    public final java.lang.Runnable buildGui = new java.lang.Runnable()
>    { @java.lang.Override public final void run(){ new Frame(); }};
>
>    public final void buildGui()
>    { java.awt.EventQueue.invokeLater( this.buildGui ); }
>
>    public static void main( final java.lang.String args[] )
>    { new Main().buildGui();  }}
>
>    I do not see a real problem with this style, assuming that
>    the assignment at hand was just to write such a simple dot
>    paint program.
>
>    The inner classes can easily share a common model and
>    identifier scope, while at the same time there is some
>    reasonable separation between the different concerns
>    of the inner classes.
>
>    Should it be required later to decouple one of these inner
>    classes more than now, this is also possible using a
>    refactor that will make it become an outer class or will
>    introduce an observer relationship. But should it not
>    be required later, no time is wasted now to implement a
>    decoupling and separation not needed.

 From a theoretical point of view V and C are not part of M.

 From the practical point of view the pattern (combined with
your non standard formatting) ensures that it takes 10
times longer to read and understand the code.

Arne


[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web