We help IT Professionals succeed at work.

Object-oriented learning with a specific example in mind.

541 Views
Last Modified: 2013-12-16
I'm new to the object oriented process and want to develop this program in C#.

I have a textbox with the application's source path within it and a button to browse for another location.
Basically I browse to a location where I want to search for files with a .PLT extension.  Whatever filenames are found they are then thrown into listbox1.  I have another button that when pressed converts the prefix of the file to having a counter in front of the name (not the path) number 01_filename, 02_filename, 03_filename...etc. and that revised list is inserted into listbox2.  Finally, I have a button that when pressed renames all the files in listbox1 to their adjusted counterpart in listbox2.

I could gather and write all this code in the click_events easily but I want to do this the true way...

What is the UML modeling I should have for the above and what should be my classnames, objects and properties?  Methods are much easier to determine but what are my objects that I should begin with?  

Much of the beginning books on object-oriented programming deal with a single object with its methods and properties.  They mention examples like dog and properties like barking, color, etc.  That has nothing to do with a business model.

What I'm doing has to do with multiple files (the total number of files could change based on various search results), then I'm throwing that it into Container1 and then a revised portion in Container2.  

Do I start off making a File class/object or a Container class/object?   What about renaming the files in Container1 and throwing that in Container2 - does that denote two objects or am I'm using the same Container object?

Could someone provide a sample class structure that would do some of the above?   Again, this is not some coding project assigned to me by school - this is for my job.  I already created a Microsoft Access program to do this using VBA.  I just want to be able to program from now on in Visual C# and have an example that I can learn from to do object oriented programming.  

Because the books sometimes are just ridiculous.   I understand there may be a concern to explain all the concepts and terminology regarding what may be displayed.  Don't worry, I have a lot of books to understand the definitions and instead I just want the class structure that fits my needs.
Comment
Watch Question

This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
yes - absolutely right.  If I get a solution that meets just that I would be perfectly happy...

but in the future I do plan to change that requirement..

Instead of putting a 01_, 02_, 03_ prefix in front of their filenames there may be another pattern I want to create...  I may also need the ability to put a different map network drive letter in front of the filepath instead of the filename.   This way I know I'm going to add different methods that take advantage of these features.... It's the nouns that I need to be clear and the way you've asked your question makes that clearer...

I just want to take what you give me thus far and adapt it further.
OK.  I was worried you were on the other side of the planet and would not see my response until the evening (my time).  So I went ahead with and wrote down my thought process as I approached this problem and designed a solution.
It's a bit long, but I wanted to be clear.
Still interested in seeing it?

Author

Commented:
oops...also there may a combination of .pdf and .plt files.  It could .doc files, any type specified... .dwgs, etc.   We're going to have the flexibity to search for particular file types specified by the . dot extension.  So if that's important to the nouns/objects.... so yea that changes things a bit.
That's OK. The benefit to OO should be that it simplifies complexity and makes things easier to change.  Which is why I never leave home without it!

Author

Commented:
sure.   I'm ready to see it.
Note - I wrote this before I learned of the new requirements you mentioned...

I think it is worth stating that the problem you have posed is what I might classify as a utility in which case OO design might be overkill. Often a utility can simply follow a procedural design that facilitates a routine operation. That said, often a simple utility blows up into a full blown application. However for the sake of discussion, here's my running thought process...

The only business objects/classes I see at first blush is PLTFile and a PLTFiles Collection. Maybe a Counter class, but we'll wait and see.
Stepping through the process it would appear they are created when a user selects .PLT files from some source. So in reality, they are not a file so much as just the specification for a file, probably containing the file name and the path to the file.

The primary business appears to be the conversion of a PLT File's name to a name with an enumeration prefixed. Though in the requirements specs there is no information about the rules (Start at 1? Require two digit numbers? Should number 1 be assigned to the first file alphabetically?). I'll assume there are no rules, just that they all get a unique numeric prefix with an underscore before the original name.
Now I ask myself, whose job should it be to rename a PLT file name? Sounds like a job for the PLTFile itself. Similar to the String object in .Net. If I want to upper case a string, I ask the string to do so.
So I create a class called PLTFile with two fields, FileName and Path. I then give it one method for prefixing a counter to the name. Note, the class is immutable, just like the string class in .NET.
Since I am the nUnit type, I write a few tests to make sure it works as expected.

Woohoo, I am done with the hard part, the true business logic has been completed and tested. Now I need to wire things together to complete my solution.

I step through the user scenario to flesh out the rest of my objects and functionality. I still am not going to worry much about the user interface here.
OK, a user will choose a bunch of files. I will need to create PLT Files from these. Currently .NET components for viewing files deals with string arrays, we will go with that as the expected format of chosen files. It does not tie us to any specific UI. Now I need to be able to convert a string array of path and file names to my PLT files. A good pattern to use for object creation is called a Factory pattern. So I will create two more classes. One, is a collection of PLT Files, and the other is a PLT File factory. The factory will have one method for now called BuildPLTFiles that will take in a string array. The factory can take care of validation needs also like making sure the files all end with the .plt extention etc.
According to our user sceanrio, the user wants to be able to view the path to these files and the names of the files. Whose job is it to provide these views....probably our PLTFile again and the collection. I will add string properties to our PLTFile to dislay the file name and path. We hate to expose data behind our objects, but truly these are identifying attributes and generally the least likely to be abused.
The user also wants to see the file name after it has been prefixed. So I can just make the method to prefix a file name public.

I think we have all the classes necessary to complete the business at hand. However, now we have to address the user interface. As I understand it we want a button that pops open a File Dialog box and two listboxes, one that displays the file names without the perfix, and one that shows them with the prefix.
On the on click event of the button we would do nothing but write a try catch block around a call to a method for handling the fact that the user wants to pick and process some files.
private void btnGetAndProcess_Click(object sender, EventArgs e)
{
  try
  {
    Handle_GetAndProcessPLTFiles();
  }catch(Exception ex){
    MessageBox.Show(ex.ToString(), "Doh! We have a problem");
  }
}
The Handle_GetAndProcessPLTFiles method would open up a dialog box and get back from it a string array of chosen files.
Next this method would call the BuildPLTFiles method of the PLTFileFactory which would return the PLTFiles collection.
(at this point the call to BuildPLTFiles could aslo return a list of issues it had like (No files given, or Files not all PLT files, etc)
Our Handle_GetAndProcessPLTFiles would now call a method of the form called DisplayPLTFiles. The DisplayPLTFiles method would loop through the PLTFiles in the PLTFiles collection and add their FileName's to the first listbox and add their Prefixed File names to the second listbox.

I apologize if at anytime I sounded condescending. I really was just trying to write down my thought process as I went through implementing an object-oriented solution for the problem you proposed. So much of what I said may have been super simple or obvious.

Author

Commented:
No this is good.  I'm just digesting it though because I've been so used to thinking of the user-interface instead of the business logic.

It would help though to see the coding with the new requirements but I know you may not have time.

I'm seeing where as you apply the logic and get a better understanding you're changing the object/class requirements to fit a design pattern called a Factory pattern...   I'm going to do some more research on that as well... it will just be a slow go for me the rest of the day... so please come back when I post another comment.
It's not a problem.  Do not hesitate to ask any questions as you digest. I don't mind taking short breaks from my work to try to clarify something when I can.
I'd be happy to provide code.
The beauty of a well designed OO application is that our concerns are separated very nicely. Each little part is just that, little. So taking two minutes to jot down some code is no big deal when it should always be just a tiny bit.

So we are on the same page, maybe you could provide me some more details on the specs.
Maybe a sentence that states the problem. And then a description of the simplest thing that works. For example...

It is a pain in the butt to rename different files according to our "rename rules", copy them to a specific directory, and get them all correct without human error.

At a bare minimum we need to allow users to upload various files (files with different extensions) and then rename and copy those files based on rules specific to files of that extension.
Rule 1: PLT files (.plt) that all share the same original path should have a unique counter prefixed to the beginning. PLT files should all be copied to the PLT directory on Server 10.
Rule 2: PDF files (.pdf) that all share the same original path should have a GUID generated and appended to the end of the file name prior to the extension and copied to the PDF directory on the Adobe server.

Make sense?

-Joe

Author

Commented:
Joe the problem revolves around Windows Explorer failure to sort files in a logical alphabetical order when certain files begin to have numbers or letters (or the mixture of both) that exist in front of the filename.  So I am renaming files or rather copying files into a temp created folder with the new sorting in a logical order that the user wants to end up as.  

It is not a matter of a rule applied to a specific file type like a rule only to a .PLT files or .PDF files but rather ....

the matter of designating what files you wish to start renaming...
Rule 1:  What kind of files do you wish to find/search in a specified folder to rename?  You need the ability to designate a specific type of file that may not exist for the time being.  What if someone creates a new program and creates a new file extension.  Then you will need to be able to type in the new file extension and allow for that new search.  And you need the ability to search for more than one file type.  In that same instance that you search for a file you may need to look for both .pdf and .plt files or other files at the same time.

then once you specify which ones how do you wish to rename them...
Rule 2:  What kind of counter method do you wish to rename the file to?  Are you able to put numbers in front and if so the bare minimum you want a double digit for numbers less than 10 (Ex: -00, 01,02,03, 04) ?  What symbol do you wish to put between the new number counter - is it a dash or underscore or some other allowable symbol?  Do you wish to use the alphabetic characters instead of numbers in front - Has to be an array of alphabetic combinations (perhaps AA, AB, AC..., BA, BB, BC..., after Z if the file listing is greater than 26 files)

I've downloaded Visual C# Express.  Today I have various activities to complete with my wife who I just found out was pregnant-neato I'm going to be a daddy.  But later tonight I plan to try to create the classes and objects.  Could you give me some time to try and attempt this?  But later on in a couple of days could you provide me the objects and classes you think this should be where I could download later and compare?
Is the problem that letters are after numbers?
I think that's pretty standard. Maybe you could provide an example of some problem file names.

I know we have had issues on a project we worked on where the users just did not want a certain collection of objects sorted alphabetically. The objects ended up getting an attribute called Sort and it was used. However, this is not the same as your case since we are talking about files in the file system outside of your application.

Congrats on the baby! As a father of 5 I can attest that the easiest days of your lives are behind you, but the very best are in front!

Author

Commented:
A4.04D REFLECTED CEILING PLAN FOURTH LEVEL AREA D.PLT
A4.04C REFLECTED CEILING PLAN FOURTH LEVEL AREA C.PLT
A4.03D REFLECTED CEILING PLAN  THIRD LEVEL AREA D.PLT
A4.03C REFLECTED CEILING PLAN  THIRD LEVEL AREA C.PLT
A4.03B REFLECTED CEILING PLAN THIRD LEVEL AREA B.PLT
A4.03A REFLECTED CEILING PLAN THIRD LEVEL AREA A.PLT
A4.02D REFLECTED CEILING PLAN SECOND LEVEL AREA D.PLT
So the A4.04 stuff is making the files list out of order as opposed to ordering by Level....so it seems.
-Joe

Author

Commented:
the above example is the end result of a request made to resort the order backwards.

If a plot is sent to a large printer and you have 300 plot files.  You want the last file to print first, the second file to print next so that you lift a large amount of papers off the plotter in order in which to send.
Interesting, I think I am starting to see the bigger picture.  I think a realistic view of how many files a person will work with at a time will help in the design of a solution.

If a person simply wants to look at 10 files and order as they see fit then that should not be too hard. If the code has to analyze 50 files and decide for itself the order they go in....that could be tough.

The users need away to rename every file in a group of files so they list in a particular order that is completely arbitrary.

So a user just loads some file names, reorders them, and then the system saves them to a new directory with a prefix that will make sure they are listed in the order the user specified.
Is this right?

Author

Commented:
Yes.

Author

Commented:
joesthebighmoe,  would I be able to see the code that would exist in the 3 classes proposed earlier?  When you state a collection I'm so used to the syntax in using VBA that I'm stumble on the correct syntax for C#.  Although it may seem as super simple or obvious - could you please list that coding for each class necessary?  

As for as the actual method of searching through a folder, or the actual coding to rename a listing of files - all that I can look elsewhere.  I was looking for the coding in my classes to get started where I could pick this up better.

Commented:
Yes joesthebighmoe, some simplistic pseudo code examples would really help illustrate what you describe.
Sorry it took so long, but I dabbled through out the day whenever I had a free moment.  I figured pseudo code would not help much if you are trying to learn C#, so I just went ahead an put some classes together.
This first bit is a FileSpec class - essentially a class encapsulating the path and file name

You should be able to create classes and then paste this code in...
using System;
/// <summary>
/// Represents a File specification which of course specifies information about a file
/// </summary>
public class FileSpec
{
  private readonly string _Path;
  private readonly string _FileName;
  
  
  internal FileSpec(string i_Path, string i_FileName)
  {
    _Path = i_Path;
    _FileName = i_FileName;      
  }
  
  /// <summary>
  /// Prefixes the given counter on to the front the file name
  /// </summary>
  public string PrefixFileNameWithCounter(int i_Counter)
  {
    string Prefix = GetPrefixForCounter(i_Counter);
    string PrefixedFileName = Prefix + this._FileName;
    return _Path + PrefixedFileName;
    
  }
  
  /// <summary>
  /// For a given "Counter" as integer, creates the string prefix used for PLT files
  /// </summary>
  private string GetPrefixForCounter(int i_Counter)
  {
    string o_Prefix = i_Counter.ToString();
    //We want our prefixes to be a minimum of two characters. E.g. 1 becomes 01, 2 becomes 02, 23 remains 23      
    if (o_Prefix.Length == 1)
    {
      o_Prefix = "0" + o_Prefix;
    }
   
    o_Prefix = o_Prefix + "_";
    
    return o_Prefix;
  }
  
  /// <summary>
  /// Utility method for separating a file name from the path (turns C:\temp\test.txt to C:\temp\ & test.txt)
  /// </summary>
  public static void SeparateFileNameFromPath(string i_FileNameWithPath, 
    out string o_Path, out string o_FileName)
  {
    //Get location of last back slash, file name should begin there
    int BackslashLocation = i_FileNameWithPath.LastIndexOf(@"\");
    
    //Throw expection if there is no backslash
    if(BackslashLocation == -1)
    {
      throw(new Exception("Unexpected format for File Name and Path [" + i_FileNameWithPath + "]"));
    }
    
    o_FileName = i_FileNameWithPath.Substring(BackslashLocation+1);
    o_Path = i_FileNameWithPath.Substring(0, BackslashLocation+1);
  }
}

Open in new window

Here is the collection for this class type. Again, in Visual C# Express you should be able to create a new class, in then replace its contents with this...
using System;
using System.Collections.Generic;
 
public class FileSpecs
{
  private readonly Queue<FileSpec> _Queue;
  
  internal FileSpecs()
  {
    _Queue = new Queue<FileSpec>();
  }
  
  internal void Add(FileSpec i_FileSpec)
  {
    _Queue.Enqueue(i_FileSpec);
  }
  
  /// <summary>
  /// The magic that allows us to write foreach statements against this collection
  /// </summary>
  public IEnumerator<FileSpec> GetEnumerator()
  {
    return _Queue.GetEnumerator();
  }
  
}

Open in new window

Here's the factory for creating FileSpecs...

using System;
 
public static class FileSpecFactory
{
  /// <summary>
  /// Builds a collection of FileSpecs based on the File names with paths given.
  /// </summary>
  /// <param name="i_FileNamesWithPaths">String array of full of file path and file name strings (e.g. C:\temp\myfile.txt)</param>
  public static FileSpecs BuildFileSpecs(string[] i_FileNamesWithPaths)
  {
    FileSpecs o_FileSpecs = new FileSpecs();
    foreach(string lp_FileNameAndPath in i_FileNamesWithPaths)
    {
      FileSpec tmpFileSpec = BuildFileSpecGvnFullPathAndFileName(lp_FileNameAndPath);
      o_FileSpecs.Add(tmpFileSpec);
    }
    return o_FileSpecs;
  }
  
  /// <summary>
  /// Builds a File Spec object given a string with the full path and file name (e.g. C:\temp\myfile.txt)
  /// </summary>
  public static FileSpec BuildFileSpecGvnFullPathAndFileName(string i_FileNameWithPath)
  {
    string FileName_lStr;
    string Path_lStr;
    FileSpec.SeparateFileNameFromPath(i_FileNameWithPath, out Path_lStr, out FileName_lStr);
    
    return new FileSpec(Path_lStr, FileName_lStr);
  }
}

Open in new window

This code is not very robust, and it is a bit removed from the end result you are after. My hope was to just get you an example in C# that shows a class that is similar to what you might have, and then the supporting cast (factory and collection) that goes with it.

Once you have added these to a project, you should be able to create a form that opens a file dialog box that allows a user to choose some files.
This file dialog box will return a string array of the file names they chose.
This string array can be passed to the FileSpecFactory so it can build a collection of FileSpecs.
Each File Spec has a method for prefixing. The results of which can be displayed or whatever.
Let me know if you need help getting that squared away.

-Joe

Author

Commented:
Joe - I could close this question now but I would like to wait until this weekend.
I may have a few more questions.  I got sick all this past weekend and Thurs-Fri and wasn't able to apply the above yet.

No rush.

Author

Commented:
Is there a place where I can upload my solution project files?
I think you can here --> http://www.ee-stuff.com/

Author

Commented:
How about an email where I could send the .sln project files?  Because of the other file types - it is not alllowing the upload.
Zip it all up into one zip file.
It allows that, doesn't it?
In fact, can't you do that below by clikcing on Attach File?

Author

Commented:
I get the extension of one or more files in the archive is not in the list of allowed extensions.  I remove all the .exe files and then its says .pdb files are not allowed... and the request continues.
I'll try something else though.
The only way it worked was to add .txt to the end of everything.


FileReShuffler.zip

Author

Commented:
Here are some plot files.  But of course you could just save as from a text file- as .plt too.

FileReShuffler.zip
What a pain!
I'll check back later this afternoon. Gotta go.
I did not get "plot" files. Both ZIP files were the same thing, the solution and classes. It won't compile because there is nothing in the Properties folder...which is true.

This should be easier to do eh?


Author

Commented:
Here are some plot files.

plot.zip

Author

Commented:
You will also need to create a C:\plot folder - sorry forgot to put in code and in solution to account for it not being there.
Still can't compile. It appears you are using something foreign to me. Your project has Properties with links to a few files. I'm not sure what this is, but my compiler says it does not like it.
Warning      1      The custom tool 'ResXFileCodeGenerator' failed while processing the file 'Properties\Resources.resx'.      
Warning      2      The custom tool 'SettingsSingleFileGenerator' failed while processing the file 'Properties\Settings.settings'.      

Author

Commented:
joesthebighmoe,

I would avoid extracting the second zip.  You want to extract the first set of contents to a location.  You will have to rename the files by taking off the .txt and making sure the .cs exists.  You have to remember to be sure the frmMain.Designer file ends with frmMain.Designer.cs instead.  I would create a new project and then Add New Item - Existing and then click Re-build.  I would ignore bringing in the .csproj and csproj.user file.   It should ask you if you want to erase over the Program.cs file and I said okay.  

It worked for me just now.
Oops you are right. When I removed .txt from frmMain.Designer.cs I accidently removed the 's' also, leaving me with frmMain.Designer.c

It compiles now.

Author

Commented:
You hadn't forgotten about me?  right joesthebighmoe?
No, not really.
I just wasn't sure what help you might need next.
You said you might close this, but might have a few more questions after you uploaded the files.
I'd be glad to help.

Author

Commented:
Could you take that attachment and make it work with the classes you describe above?
Ignoring the work you already did in the classes you sent?

Author

Commented:
yes.
Ok, I can take a stab at that.
Do you have a junk email address to send a Zipped application to?
Look for email from hee@nospam.com

Author

Commented:
Is there anyway I can at least get rid of the last posting? to remove my email address?
Ummmmmm. Good question.
You might be able to delete this entire question.

Author

Commented:
I'd make sure you get the points somehow - even if I have to post another question with some copy and paste including your replies.
Do what you need to do.
Did you get my email?

Author

Commented:
Yes.  Thank you this helps a lot.

I understand what FileSpec.cs and FileSpecFactory but where I'm getting confused is on the FileSpecs.cs class?  I never seen the Queue command before - what is its role as to how this is related?
It is a collection object.
I am just wrapping it up to use its functionality for holding a collection of objects.
A better answer:
A collection object is used to contain multiple objects. Like an array (maybe most common collection type).
The Queue class is one of many collection objects the .Net framework provides.
When we are modeling we often need a class to represent a specific collection of things. We could just use any collection class, like the Queue without wrapping it up. However, the Queue class exposes about 20 different methods, none of which has to do with the business being modeled.
A better solution is to create a specific business object collection that uses a .Net collection object to do its heavy lifting. Our specific business object collection then exposes only methods that would make sense in the model.
Boy, did I just make that more clear or more muddy?

Author

Commented:
Thank you sincerely for all your replies.

The example has helped out tremondously.

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.