Better Faster Lighter Java [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Better Faster Lighter Java [Electronic resources] - نسخه متنی

Justin Gehtland; Bruce A. Tate

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








9.8 The Console Interface


Console interfaces generally


share a common usage idiom: provide a
method for invoking the interface without arguments, but also allow
for runtime decisions by providing for command flags. If the number
of arguments does not match your expectations, return a usage
statement.

If a user provides no command flags to our console interface, it
launches into search mode. We'll allow users to
enter search terms on the command line and return results. To quit,
they just press Enter.

In order to launch an indexing event, the user passes in a flag in
this format: /i:
http://www.somedomain.com/. This simply
provides the starting URL from which the rest of the indexable pages
are eventually discovered. If the user invokes the indexer,
we'll bypass the search. If not, we go into search
mode.

According to typical standards, we should allow the user to enter a
help flag (we'll use /?) that produces the usage
message. Any other number of or type of flag cause us to write out
the usage message and quit.

Here are the utility methods:

private static void writeUsage( )
{
System.out.println("Usage: java ConsoleSearch");
System.out.println(" -- /i:http://YOUR_INITIAL_INDEX_PATH");
System.out.println(" -- /?:show this message");
}
private static boolean checkArgs(String[] args)
{
if(args.length < 2 && args.length > 0 && args != null)
{
if(args[0].startsWith("/i") || args[0].startsWith("/?"))
{
return true;
}
}
return false;
}
private static String getIndexFlag(String[] args)
{
for(int i=0;i<args.length;i++)
{
if(args[i].startsWith("/i:"))
{
return args[i].substring(3, args[i].length( ));
}
}
return ";
}

The last method, getIndexFlag, examines the
args collection to see if the user passed in the
/i flag. If so, it returns the URL that is passed
in after the flag.

That only leaves the entry point to the application:

public static void main(String[] args)
{
// get configured index path from IndexPathBean
ConfigBean config = new ConfigBean( );
String indexPath = config.getCurIndexPath( );
if(indexPath == ") return;
// check args for index flag, retrieve initial page, execute index
if(!checkArgs(args)) {
writeUsage( );
return;
}
String indexInitialPage = getIndexFlag(args);
if(indexInitialPage != ")
{
doIndex(indexInitialPage);
return;
}
// Allow multiple queries from command line
BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
try {
while (true) {
System.out.print("Query: ");
String line = rdr.readLine( );
if (line.length( ) == 0) {
break;
}
QueryBean query = new QueryBean("contents", indexPath, line);
query.execute( );
HitBean[] hits = query.getResults( );
for(int i = 0;i<hits.length;i++)
{
System.out.println(hits[i].getScoreAsString( ) + " " +
hits[i].getUrl( ));
}
}
}
catch(Exception e)
{
e.printStackTrace( );
}
}

This single method provides everything our human and machine users
could want. The live users can execute the main method and start
interactively querying the index. Conversely, they can pass in the
/i: flag and operate just the indexing/crawling
functionality.

First, make sure the arguments are correct; if
they're not, call writeUsage and
then break. Check to see if the user is asking for an index instead
of a search. If she is, call doIndex, then return.
If not, allow the user to enter a query and execute the search,
returning a simply-formatted result set. If anything goes wrong,
print out the stack trace.

Here's the doIndex method:

private static void doIndex(String indexflag)
{
try
{
ConfigBean config = new ConfigBean( );
String nextIndex;
try
{
nextIndex = config.getNextIndexPath( );
}
catch(Exception ex)
{
return;
}
IndexLinks lts = new IndexLinks(nextIndex, config.getMaxLinks( ),
config.getSkippedLinksFile( ));
lts.initFollowPrefixesFromSystemProperties( );
lts.initAvoidPrefixesFromSystemProperties( );
lts.setInitialLink(indexflag);
config.flipIndexPath( );
}
catch(Exception e)
{
// handle error
}
}

First, we retrieve the alternate index path from
the ConfigBean. Remember, we need to create the
index, but still allow other users to coninue to
search it. Create a new instance of our
IndexLinks class, passing in the alternate index
path plus the MaxLinks and
SkippedLinksFile values from our
ConfigBean. Set up the avoid and follow link
collections and kick off the index process. If everything succeeds,
flip the indexes via the ConfigBean.flipIndexPath(
)
method.

The console interface is simple enough that it
doesn't need a controller layer between it and our
business logic. In fact, the console interface looks a lot like a
simple controller layer. It pieces together all three services
without knowing anything about their internal configuration,
demonstrating good interface separation. It is entirely focused on
providing entry points to the application services to our users and
returning results.


9.8.1 Principles in Action


Keep it simple: no configurable schedule for invoking services, allow
indexing output to show through to user

Choose the right tools: JUnit

Do one thing, and do it well: just read from command lines and return
search results

Strive for transparency: no internal


knowledge of services

Allow for extension: none



/ 111