3 Replies - 738 Views - Last Post: 07 February 2011 - 07:05 AM Rate Topic: -----

#1 skifozoa  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 37
  • Joined: 16-January 11

Question on abstract classes (is this correct usage of them? OOP best

Posted 06 February 2011 - 06:23 PM

Hey guys

I'm writing a program which allows a user to browse through his file system, select certain files and compile the contents of these files (images, icons, sounds, etc...) into .NET resources. I know that Visual Studio does this, but the program I'm writing is going to be the basis of a tutorial I'm planning to write on .NET resources, which explains in more detail what happens in behind the scenes in visual studio. Inspired by This topic.

Writing this program I was facing a problem for which I found a solution, but I'm afraid this might not be a best practice. Since a tutorial is supposed to contain nicely written code I wanted to check my ideas first and maybe search for a better solution.

On to the problem

Every time the user selects a file, the type of file is determined (by means of the file's extension) and the contents of that file are converted into the most fitting resource object (custom made classes). This resource object is then added to a collection of resource objects. The compiler will then run through each resource object in the collection and write it on the .resources file.

The following lines of code are a brief and error prone overview of how I want to implement this feature. Note that they still contain pseudo code.

My question would be, more concretely:
Am I following best practices by defining an abstract resource class which enables me to {a} determine the object's type in the static pseudoconstructor and {b} to place all the instances of the different classes in one collection of the abstract class, this way, in the end I only have to loop through 1 collection in stead of a collection for each class

Is this good code or not? How would you do it instead? (mind you that I'm only writing c# since medio january and this is the first time I intend to use inheritance)

Thanks for your input!

//Some members of the main form

private Collection<Resource> ResourceCollection = new Collection<Resource>();

private void eventhandlernewresourcebuttonclick(object Source, EventArgs e)
{
	ResourceCollection.Add(Resource.NewResource(namebox.Text,locationbox.Text));
}

private void compilebuttonclick(object Source, EventArgs e)
{
	//for each resource currentresource in ResourceCollection
	currentresource.Output();
}


public abstract class Resource
{
	public abstract void Output();
        //pseudoconstructor
	public static Resource NewResource(string name, string location) //Here I fake a constructor
	{
		//decide upon type (based on last4 characters of location string, the extension)
		//based on type (switch case statements)
		return new ResourceTypeImage(name,location);
		//or
		return new ResourceTypeFile(name,location);
		//or
		return new ResourceTypeIcon(name,location);
		//etc...
		//etc...
		//etc...
	}
}

public class ResourceTypeImage : Resource
{
	private Image Content;
	private string Name;
	public override void Output()
	{
		//do something specific with content and Name
	}
	//constructor
	public ResourceTypeImage(string name, string location)
	{
		Content = Image.FromFile(location);
		Name = name;
	}
}

public class ResourceTypeIcon : Resource
{
	private Icon Content;
	private string Name;
	public override void Output()
	{
		//do something specific with Content and Name
	}
	//constructor
	public ResourceTypeIcon(string name, string location)
	{
		//load icon at Location and place it into Content etc...
	}
}

public class ResourceTypeFile : Resource
{
	private byte[] File;
	private string Name;
	public override void Output()
	{
		//do something specific with File and Name
	}
	//constructor
	public ResourceTypeFile(string name, string location)
	{
		//read file at location and place it into File etc...
	}
}


This post has been edited by skifozoa: 06 February 2011 - 06:25 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Question on abstract classes (is this correct usage of them? OOP best

#2 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 992
  • View blog
  • Posts: 972
  • Joined: 30-September 10

Re: Question on abstract classes (is this correct usage of them? OOP best

Posted 07 February 2011 - 04:18 AM

I like that you've used an abstract class here. Coding to an abstract class/interface is usually a good way to go. If the 'Name' field is going to be present in all subclasses, you could put that in the abstract class too.


With part {b}, I think you are certainly doing the right thing. I'm not sure about part {a}...

I think that if you want to return a certain object based on some condition, I think you should encapsulate that logic out of the core classes as that conditional logic will likely change a lot in the future as more extensions come out etc. It certainly shouldn't be in the abstract class type as all the concrete classes will then inherit all that horrible conditional logic.

What you could do in this situation is create a factory class that will manufacture your resource objects for you. An example for this situation could be:

public static class ResourceFactory{

public static Resource CreateResource(string name, string location) 
{
		//decide upon type (based on last4 characters of location string, the extension)
		//based on type (switch case statements)
		return new ResourceTypeImage(name,location);
		//or
		return new ResourceTypeFile(name,location);
		//or
		return new ResourceTypeIcon(name,location);
		//etc...
		//etc...
		//etc...
	}
}




That is the simplist possible way of implementing a factory, but it needs to be as that's not going to be the focus of your tutorial :).

You have a factory method that can create your resource objects on demand but, crucially, all the nasty, ever changing conditional logic held within is encapsulated well away from the core code base. Thus, making future changes very painless. You can then call this CreateResource() method, passing in the name and location, and you will get the newly configured Resource object back, just as you wanted!

This post has been edited by CodingSup3rnatur@l-360: 07 February 2011 - 06:13 AM

Was This Post Helpful? 1
  • +
  • -

#3 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5932
  • View blog
  • Posts: 12,855
  • Joined: 16-October 07

Re: Question on abstract classes (is this correct usage of them? OOP best

Posted 07 February 2011 - 05:46 AM

Looks good. I agree with a factory. I don't like the static Create, though. I'd go with a self create and the ability to have an empty instance.

e.g.
public interface Resource { 
	string Name { get; };
	void Output();
	bool IsResource(string name);
	bool IsValid();
	Resource Create(string name, string location);
}

public class ResourceCollection : Collection<Resource> {
	private ResourceFactory factory = new ResourceFactory()
	public bool Add(string name, string location) {
		Resource res = factory.Create(name, location);
		if (res!=null && res.IsValid()) { 
			this.Add(res);
			return true;
		}
		return false;
	}
}

public class ResourceFactory {
	List<Resource> available;
	public ResourceFactory() {
		available = new List<Resource>();
		available.Add(new ResourceTypeImage());
		available.Add(new ResourceTypeFile());
		//...
	}
	public Resource Create(string name, string location) {
		foreach(Resorce r in available) {
			if (r.IsResource(name)) { return r.Create(name, location); }
		}
		return null;
	}
}

abstract class ResourceBase : Resource {
	private string name;
	
	public ResourceBase() { this.name = null; }
	public ResourceBase(string name) { this.name = name; }
	public string Name { get { return this.name; } }
	public bool IsValid() { return this.name != null; }
	protected void Invalidate() { this.name = null; }
	
	public abstract void Output();
	public abstract bool IsResource(string name);
	public abstract Resource Create(string name, string location);
}


class ResourceTypeImage : ResourceBase {
	private Image content;
	public ResourceTypeImage() : base() { }
	public ResourceTypeImage(string name, string location) : base(name) { 
		try {
			content = Image.FromFile(location);
		} catch {
			Invalidate();
		}
	}
	public override void Output() { /* still needs code */ }
	public override bool IsResource(string name) {
		name = name.ToLower();
		foreach(string ext in new string[] {"gif","jpg","bmp"}) {
			if (name.EndsWith("." + ext)) { return true; }
		}
		return false;
	}
	public override Resource Create(string name, string location) { return new ResourceTypeImage(name, location); }
}


Was This Post Helpful? 2
  • +
  • -

#4 skifozoa  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 37
  • Joined: 16-January 11

Re: Question on abstract classes (is this correct usage of them? OOP best

Posted 07 February 2011 - 07:05 AM

Thank you both for your time. Your replies were insightful.

I understand the need for a factory now and will try to implement it as good as I can in the way you have suggested. Thank you also for replacing some of my pseudo code by c# code, this will save me some time browsing the MSDN pages in search of the correct classes and methods.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1