English 中文(简体)
A better design? Same object, different possible states
原标题:

I have a very simple application which consists of an ASP.NET front end site, with a WCF Windows Service doing the heavy lifting back-end logic.

The user has one simple page where he selects some parameters and pushes a submit button. The page calls the WCF service and passes it the parameters. The service instantiated an instance of a Job class, sending the parameters to the constructor, then calls a Run() method which does all the work of - inserting a job record into a database with the users name, time started, etc... Makes a request to a 3rd party vendor, takes the data, puts it in the database, does some other business logic then marks the job as completed.

The user then has a second simple page where he can now search for his job (a searchable combo box sorted by date, displaying multiple fields related to that job) and then display the data corresponding to that job on the screen - (most of the fields from the job table, e.g. started time, completed time, status, etc, displayed as labels in a panel) and the actual data we pulled from the 3rd party vendor (rendered as a grid, below the panel).

Now on to my question - so I have a Job class which has all the fields mentioned above, along with its public Run() method and constructors. It has a few simple private functions, and several private members which are interfaces to classes like IParser, IVendorConnection, IDataAccess - the classes which do all the actual work described above.. the actual Job class and Run() method doesn t do much actual work, pretty much just delegates work to its composite objects (makes for good testability among other things).

Now, this Job class has 3 different possible uses / states. Its main use is inside the Service, for use of the Run() function to literally run a job. It also has 2 other uses - acting as the model for the panel I described above, and acting as a model for the combo box I described above. The job class has 3 public constructors, each one setting it up for one of the 3 states. In all cases, each different state only cares about certain members that the other 2 states don t care about - in some cases some of the members are used in all 3 states. The combo box state is the simplest - in this case I only want 3 readonly fields. In the panel state I care about 6 readonly fields.. in the work state I am basically creating these field values as the job progresses - and they should all be private.

I m just looking for a cleaner way to do this. If I instantiate a Job class in state A, I know that accessing member X will not work, or calling function Y will fail. However it s still compilable code.

I m sure that others have faced this problem before. I was thinking of having a base Job class marked as MustInherit/abstract, and then having 3 derived classes, one for each state. Put the shared members in the base and the state-specific ones in the derived, and just use the derived classes in my code where appropriate. This seems simple enough for my purposes and solves my problem. Perhaps I could also have some kind of JobFactory... I guess I m just looking for how other people solved this as maybe I m not thinking outside the box enough... I have had many classes be state machines before in my hobbyist game development days - but that was different, because instances of those classes could change states (e.g., an Enemy class could have its state changed from attack_mode to waiting ) In my case, there is no changing states - once created, a Job must stay in its state and never try to behave in a different one. Tracking state and throwing exceptions if a method/member is used while not in a given state seems brittle and too much work. Any suggestions based on how you have solved this problem before? And is what I m trying to do overkill? If the Job started to get more and more different states, I would think not - but maybe if it did get that many different states then I need to think of splitting it up into different classes anyway... Just looking for your 2 cents.

最佳回答

Your idea to create a single base class job with 3 derived classes sounds exactly like what I would do too. Creating a JabFactory might further help this design. It might be bad practice to create an object where parts of the object is not used or illegal to be used under certain circumstances. So creating the derived classes with only the necessary parts is clearly the better design. It is not overkill.

问题回答

暂无回答




相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签