Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Given the following set of classes:

Camera, Photo, Photoshoot, Subject.

How would they interact to model the following sentence?

The next subject is called and has their photo taken.

I want to see if there is a preferred solution.

Edit:

Sorry I should have said in C#.

share|improve this question
    
"Called" how? With a telephone? With the human voice, from a waiting room? –  Kyralessa Apr 27 '11 at 1:08
    
Any of the above, feel free to use a little programmer's license if you need an extra class here or there. –  Grokodile Apr 27 '11 at 1:11

7 Answers 7

Photoshoot p = new Photoshoot(new Camera("Name of really expensive camera"));
Subject bob = new Subject("Bob");
Photo photo = p.TakePhotoOf(bob);

Is this good?

share|improve this answer
    
It is good. How would you implement TakePhotoOf(Subject subject)? I think the Camera should take (/create) the Photo. –  Grokodile Apr 27 '11 at 0:49

There are a lot of different ways of looking at this. If I were in an interview, I'd go with this.

Photoshoot shoot = new Photoshoot(
    new Camera("Fuji"),
    new Subject("Bill"),
    new Subject("Dave"),
    new Subject("Claire")
    );

IEnumerable<Photo> photos = shoot.TakeAllPhotos();

Where

class Photoshoot
{
    private readonly IEnumerable<Subject> _subjects;
    private readonly Camera _camera;

    public Photoshoot(Camera camera, params Subject[] subjects)
    {
        _subjects = subjects;
        _camera = camera;
    }

    public IEnumerable<Photo> TakeAllPhotos()
    {
        List<Photo> photos = new List<Photo>();

        foreach(Subject subject in _subjects)
        {
            // Here is the interaction in question
            Call(subject);
            _camera.TakePhotoOf(subject);
        }

        return photos;
    }
}

So the interaction is this:

The TakeAllPhotos method of the Photoshoot class cycles through the Subjects of the photoshoot, Calls a subject then uses its Camera to TakePhotoOf that subject.

On a different day, I might pass camera to the TakeAllPhotos method, but today I'm arguing that the camera belongs to the photoshoot.

Note also that I passed subject to the (as yet undefined) Call method of the Photoshoot rather than calling a Call method on the subject. The subject shouldn't know how to call itself, in my opinion.

These are the kinds of conversations an interviewer wants you to have. The specific interaction is not going to be that important.

share|improve this answer
    
I like this, the "photoshoot" wraps everything up nicely without any further knowledge of the domain/problem. Alternatively could have had camera.TakePhotosOf(photoshoot.CallNextSubject()) as others have pointed out. –  Thomas James Apr 27 '11 at 10:44

There is no preferred solution. It doesn't matter if you have Camera.TakePhoto(subject) or Photoshoot.TakePhoto(subject, camera). Even with a full set of requirements it may not make much difference. Some designs may be better than others, but there is never a single 'best' design.

share|improve this answer

all of these are valid; there may be more models as well, 'best' depends on what you need for your application

//The next subject is called and has their photo taken.

Photo pic = photoSession.Shoot(photoSession.NextSubject);

Photo pic = myCamera.Shoot(photoSession.NextSubject);

Photo pic = photoSession.ShootNextSubject(myCamera);
share|improve this answer

Assuming Subject Subject, Camera and Photo as classes, TakePhoto as a method(may be extension method) of Subject class and PhotoShoot as a static method-

IEnumerable<Subject> SubjectCollection = Factory.SubjectCollectionGenerator();
Camera cam = new Camera("Camera Name");

IEnumerator<Subject> subjectEnumerator = SubjectCollection.GetEnumerator();
subjectEnumerator.MoveNext();
Subject calledSubject = subjectEnumerator.Current;
IEnumerable<Photo> photosTaken = StaticClass
                              .PhotoShoot(SubjectCollection, calledSubject, cam);

Where the PhotoShoot is-

static IEnumerable<Photo> PhotoShoot(Enumerable<Subject> SubjectCollection,
                                     Subject calledSubject,
                                     Camera cam)
{ return SubjectCollection.Select( s => calledSubject.TakePhoto(s, cam)); }

Or, for all the subjects the PhotoShoot can be-

static IEnumerable<Photo> PhotoShoot(Enumerable<Subject> SubjectCollection,
                                     Subject calledSubject,
                                     Camera cam)
{ return
           from calledSubject in SubjectCollection
           from s in SubjectCollection
           select calledSubject.TakePhoto(s, cam));
}
share|improve this answer
    
-1: over-engineered - factory –  Thomas James Apr 27 '11 at 10:41
    
Interesting that he's approaching it using LINQ though, I certainly wouldn't have considered tackling it in that way. –  Grokodile Apr 27 '11 at 23:33

From the sentence in your question the implication seems to be in this case that a photoshoot contains many photos, each photo has one subject and is taken with a single camera. This is not a general solution, but for your specific question (homework? :-) ) the classes would look something like:

class Photoshoot
{
 List<Photo> photos;
 ...
}

Class Photo
{
 Camera camera
 Subject subject;
 ...
}

Class Camera 
{
/* camera properties */
}


Class Subject
{
 /* subject properties */
}

For a more general solution you might want to add multiple subjects to a photo, and no doubt more changes, but for the data you gave this seems to be the minimal set of classes you need.

share|improve this answer

This is my version, which is similar to the many lines of homework I'd already submitted before asking the question, chuckle:

  public class Camera{
      public event EventHandler<PhotoTakenEventArgs> PhotoTaken;
  }

  public class PhotoTakenEventArgs:EventArgs{
      public string PhotoPath{get;}
  }

  public class Coordinator{
      Camera TheCamera{get;}
      PhotoShoot ActiveShoot{get;set;}

      public void NewPhotoshoot(){
          IEnumerable<Subject> subjects = ImportSubjectList();
          Photoshoot shoot = new Photoshoot(subjects);
      }

      public void CallSubject(int subjectIndex){
          ActiveShoot.CurrentSubject = ActiveShoot.Subjects[subjectIndex];
      }

      private void CameraPhotoTakenHandler(object sender, PhotoTakenEventArgs e){
          Photo photo = new Photo(e.PhotoPath);
          ActiveShoot.CurrentSubject.AddPhoto(photo);
      }
  }
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.