Convert base type to derived type

A base class is a task. There are several derived classes such as PhoneCall, Fax, Email .... .NET 3.5 framework and C # language

In our application, we want to create some automatic tasks based on certain rules for the client. E.g. if the client has been registered for 30 days, the task will be created by the rule engine.

Then the task owner will be able to convert this task to PhoneCall, Fax ..... based on the script. In addition, converting PhoneCall to fax or email, or vice versa, will be another requirement.

1) Should there be a transformed class that should facilitate this conversion, or should each business object allow methods for conversion?

2) If there are any design templates or recommendations that someone can provide, this will be great.

Pratik

+3
source share
3 answers

Inheritance is not necessarily the best way to model problems when type instances can change over time.

Instead, you might consider using a composition. Sort of:

class Task
{
    private TaskDetail m_Detail;

    public TaskDetail Detail { get { return m_Detail; } }
}

abstract class TaskDetail { ... }

class PhoneCallDetail : TaskDetail { ... }
class FaxDetail : TaskDetail { ... }
class EmailDetail : TaskDetail { ... }

Tasks will not change when their task data moves from one type to another. You will also need to implement some utility code to convert between different types of tasks, if necessary.

So, a usage example might look like this:

Task theTask = new Task( ... );
theTask.ConvertToEmail(); // internally establishes this as an email task

EmailDetail detail = (EmailDetail)theTask.Detail;
detail.EmailAddress = "wiley.coyote@acme.com";

theTask.ConvertToFax();   // may transfer or lose some detail...
FaxDetail faxDetail = (FaxDetail)theTask.Detail;
faxDetail.FaxDate = DateTime.Now;

// and so on.

, , , Task , , ; :

Task someTask = ...;
if( someTask.Detail is EmailDetail )
{ 
    EmailDetail detail = (EmailDetail)someTask.Detail;
    /* operate on email detail ... */
}
else if( someTask.Detail is FaxDetail )
{
    FaxDetail detail = (FaxDetail)someTask.Detail;
    /* operate on fax detail ... */
}

. , , , .

- , , , , .

, , - . / . . , , .

. ( ), :

abstract class TaskDetail
{
    public abstract object this[string key] { get; }
}

public class FaxDetail : TaskDetail
{
    public string FaxNumber { get; set; }
    public DateTime DateSent  { get; set; }

    public override object this[string key]
    {
        get
        {
            switch( key )
            {
                case "FaxNumber": return FaxNumber;
                case "DateSent":  return DateSent;
                default:          return null;
            }
        }
    }
}

public class EmailDetail : TaskDetail
{
    public string EmailAddress { get; set; }
    public DateTime DateSent { get; set; }

    public override object this[string key]
    {
       get
       {
           switch( key )
           {
               case "EmailAddress": return EmailAddress;
               case "DateSent":     return DateSent;
               default:             return null;
           } 
       }
    }
}

// now we can operate against TaskDetails using a KVC approach:
Task someTask;
object dateSent = someTask.Detail["DateSent"]; // both fax/email have a DateSent
if( dateSent != null )
   // ...
+4

1) factory

2) , , . , .

0

, PhoneCall, , .

, , PhoneCall, . PhoneNumber Customer, , , ..

TaskType Task , Task . , , ..

, . Decorator.

0
source

Source: https://habr.com/ru/post/1759518/


All Articles