error checking without if_else statements, possible?
hi,
i was thinking that if i have a lof of textfields and i want to check whether the user has filled in all the required fields or not. The simplest way of doing this is to use a series of if-else statements. But can it be done in another way which is more OO style or without using of if-else statements?
thanks!
[334 byte] By [
kl001480] at [2007-9-30 19:48:02]

> i was thinking that if i have a lof of textfields and
> i want to check whether the user has filled in all the
> required fields or not. The simplest way of doing this
> is to use a series of if-else statements. But can it
> be done in another way which is more OO style or
> without using of if-else statements?
Yes you can do this in a more OO way, you need to make use of two fundamental OO techniques, polymorphism, and delegation.
Polymorphism allows you to handle a bunch of things (i.e. fields) in a uniform manner, (i.e. validation).
The second technique is to use delegation, get the fields to validate themselves.
Checkout the ValueObject and ValueAssembler patterns.
Firstly you need to create a common base for your text fields, this could be concrete if you wanted to use it for all your fields, or abstract if you wanted to specialise some of your fields.
interface ValueObject {
boolean validate() ;
}
abstract class StringValueObject {
String string;
boolean validate() {
super.validate() ;
}
}
abstract class PersonNameObject {
String string;
boolean validate() {
super.validate() ;
}
}
abstract class AddressObject {
String string;
boolean validate() {
super.validate() ;
}
}
// define your text fields as an array of the common base.
...
ValueObject[] record = new ValueObject[MAX_FIELDS] ;
// process your text fields polymorphically.
for( int i =0 ; i<MAX_FIELDS ; i++) {
record[i].validate() ;
}
>
look up Lohka's books (Prof vb5 and vb6, and expert c#), there is a BrokerRules mechanism that should apply.
This will teach me not to type the code directly into the form.String value object should implement the ValueObject interface and PersonNameObject & AddressObject should extend it and be final not abstract.
i m still not really understanding...can provide some examples for me? especially the delegation?
Hi,
You could do something like this:
/* StringValidator.java */
/* This interface describes a method for validating strings */
public interface StringValidator
{
boolean validateString( String string );
}
/* NotEmptyStringValidator.java */
/* This is an example implementation, you would have others */
/* NB. It is a singleton */
public class NotEmptyStringValidator
implements StringValidator
{
private static final NotEmptyStringValidator INSTANCE =
new NotEmptyStringValidator();
public static NotEmptyStringValidator getInstance()
{return INSTANCE;}
private NotEmptyStringValidator() {}
public boolean validateString( String string )
{
if ( string == null ) return false;
if ( string.length() == 0 ) return false;
if ( string.trim().length() == 0 ) return false;
return true;
}
}
/* ValidatedTextField.java */
/* This class connects a validator to a text field */
import javax.swing.*;
public class ValidatedTextField
{
private final JTextField textField;
private final StringValidator stringValidator;
public ValidatedTextField( JTextField textField ,
StringValidator stringValidator )
{
if ( textField == null ) throw new
NullPointerException( "textField" );
if ( stringValidator == null ) throw new
NullPointerException( "stringValidator" );
this.textField = textField;
this.stringValidator = stringValidator;
}
public boolean validate()
{ /* delegates validation to the StringValidator */
return stringValidator.validateString( textField.getText() );
}
}
/* ValidatedTextFields.java */
/* This class is for holding, and validating, many text fields */
import java.util.*;
import javax.swing.*;
public class ValidatedTextFields
{
private final Collection fields = new ArrayList();
public ValidatedTextFields() {}
public void add( JTextField textField ,
StringValidator stringValidator )
{
fields.add( new ValidatedTextField( textField , stringValidator ) );
}
public boolean validate()
{
for ( Iterator i = fields.iterator() ; i.hasNext() ; )
{
ValidatedTextField f = (ValidatedTextField) i.next();
if ( ! f.validate() ) return false;
}
return true;
}
}
/* ValidatedTextFieldTest.java */
/* An example program to test the classes above */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ValidatedTextFieldTest
extends JFrame
implements ActionListener
{
private final JButton validateButton;
private final JLabel label;
private final JButton quitButton;
private final ValidatedTextFields fields;
public static void main( String[] argv )
{
ValidatedTextFieldTest frame = new ValidatedTextFieldTest();
frame.pack();
frame.setVisible( true );
return;
}
public ValidatedTextFieldTest()
{
StringValidator notEmpty = NotEmptyStringValidator.getInstance();
JTextField a = new JTextField( 20 );
JTextField z = new JTextField( 20 );
validateButton = new JButton( "Validate" );
label = new JLabel( "Blah blah" );
quitButton = new JButton( "Quit" );
fields = new ValidatedTextFields();
fields.add( a , notEmpty ); /* connect fields and validators here */
fields.add( z , notEmpty );
getContentPane().setLayout( new GridLayout(5,1) );
getContentPane().add( a );
getContentPane().add( z );
getContentPane().add( validateButton );
getContentPane().add( label );
getContentPane().add( quitButton );
validateButton.addActionListener( this );
quitButton.addActionListener( this );
}
public void actionPerformed( ActionEvent e )
{
if ( e.getSource() == quitButton ) System.exit(0);
if ( fields.validate() )
label.setText( "GOOD" );
else
label.setText( "BAD" );
}
}
This doesn't get rid of the if/elses of course, but it does put them in a validator class which is where they probably belong. Also the validators know nothing of gui text fields, which is as it should be.
Ol.
0s at 2007-7-7 0:35:50 >

as close as i can remember Lohtka's 'intent', it is in c#. not sure if it is what you want.
1using System;
2using System.Collections;
3using System.Diagnostics;
4
5namespace BrokenRulesFramework
6{
7public interface ObservableInterface
8{
9void addObserver( BrokenRulesInterface ob );
10}
11
12public interface ObserverInterface
13{
14
15}
16
17public interface BrokenRulesInterface : ObserverInterface
18{
19void NoBrokenRules( Object obj );
20void BrokenRules( Object obj );
21}
22
23public class BrokenRules : ObservableInterface
24{
25private Hashtable brokenRules = new Hashtable();
26private Hashtable observers = new Hashtable();
27
28public void addObserver( BrokenRulesInterface ob )
29{
30this.observers.Add( ob, ob );
31}
32public Boolean IsValid( String rule, Boolean cond )
33{
34if( cond )
35{
36this.brokenRules.Remove( rule );
37}
38else
39{
40this.brokenRules.Add( rule, cond );
41}
42notify( rule, cond );
43return cond;
44}
45private void notify( String rule, Boolean cond )
46{
47foreach( Object obj in this.observers )
48{
49DictionaryEntry d = (DictionaryEntry) obj;
50BrokenRulesInterface ob = (BrokenRulesInterface) d.Value;
51if( cond )
52{
53ob.NoBrokenRules( rule );
54}
55else
56{
57ob.BrokenRules( rule );
58}
59}
60}
61public Boolean IsValid()
62{
63return 0 < this.NumberOfBrokenRules() ? false : true;
64}
65public int NumberOfBrokenRules()
66{
67return this.brokenRules.Count;
68}
69public Boolean IsRuleBroken( String rule )
70{
71return this.brokenRules.Contains( rule );
72}
73public Hashtable GetBrokenRules()
74{
75return this.brokenRules;
76}
77}
78}using System;
79using System.Collections;
80using System.Diagnostics;
81using BrokenRulesFramework;
82
83namespace CallingClass
84{
85public class CallingClass : BrokenRulesInterface
86{
87private BrokenRules br = new BrokenRules();
88private int field1;
89
90public BrokenRules GetBrokenRules()
91{
92return this.br;
93}
94public CallingClass()
95{
96br.addObserver( this );
97}
98public int getField1()
99{
100return this.field1;
101}
102public void setField1( int value )
103{
104if( br.IsValid( "field1", 0 < value ) )
105this.field1 = value;
106}
107public void NoBrokenRules( Object obj )
108{
109Debug.WriteLine( "no broken rule: " + obj );
110}
111public void BrokenRules( Object obj )
112{
113Debug.WriteLine( "Broken rule: " + obj );
114}
115}
116}
117using System;
118using System.Diagnostics;
119using System.Collections;
120
121namespace CallingClass
122{
123/// <summary>
124/// Summary description for Class1.
125/// </summary>
126class Class1
127{
128/// <summary>
129/// The main entry point for the application.
130/// </summary>
131[STAThread]
132static void Main(string[] args)
133{
134CallingClass cc = new CallingClass();
135cc.setField1( 0 );
136Debug.WriteLine( "br #: " + cc.GetBrokenRules().NumberOfBrokenRules() );
137Hashtable ht = cc.GetBrokenRules().GetBrokenRules();
138foreach( Object obj in ht )
139{
140DictionaryEntry d = (DictionaryEntry) obj;
141Debug.WriteLine( "k: " + d.Key + ", " + d.Value );
142}
143Debug.WriteLine( "f1: " + cc.getField1() );
144Debug.WriteLine( "isV: " + cc.GetBrokenRules().IsValid() );
145cc.setField1( 10 );
146Debug.WriteLine( "br #: " + cc.GetBrokenRules().NumberOfBrokenRules() );
147ht = cc.GetBrokenRules().GetBrokenRules();
148foreach( Object obj in ht )
149{
150DictionaryEntry d = (DictionaryEntry) obj;
151Debug.WriteLine( "k: " + d.Key + ", " + d.Value );
152}
153Debug.WriteLine( "f1: " + cc.getField1() );
154Debug.WriteLine( "isV: " + cc.GetBrokenRules().IsValid() );
155}
156}
157}
output:
br #: 1
k: field1, False
f1: 0
isV: False
no broken rule: field1
br #: 0
f1: 10
isV: True
