C
C#3y ago
N0b0dy

[Help] understanding Architecture of a parcel system

Hi, I am working on a post system which has two classes, standard and express. I am using Finite state machine to track my order from dispatch to Deliver. My architecture is like
abstract class post
abstract class post
where I have all the details about the order
class standPost:post
class standPost:post
standpost inheritances all the properties of the post class and I have added a couple status for this class. Also, I have different status for standard deliver, such as dispatch, in transit, and many more. Is there any way that I can change these standPost status automatically, so the client get notification? If someone can help me or guide, that would be appreciated. thanks
56 Replies
麺麭
麺麭3y ago
I'm not sure I understand. I think I'd need to see a simplified version of your code to get a better idea
N0b0dy
N0b0dyOP3y ago
@aes I can share my code
麺麭
麺麭3y ago
I built a state machine once that lets clients register Actions to events and transitions in my state machine. That could be similar to what you mean by client getting notification
N0b0dy
N0b0dyOP3y ago
Yes something like that, Basically If you can help to understand the architecture that would be helpful
麺麭
麺麭3y ago
You can try to share your code. I am not familiar with the domain of parcel and shipping
N0b0dy
N0b0dyOP3y ago
How can I share my code?
麺麭
麺麭3y ago
uhhh... screenshots maybe? Or github? I guess first just tell me what you're trying to do
N0b0dy
N0b0dyOP3y ago
Sure, For example,
Angius
Angius3y ago
$code
MODiX
MODiX3y ago
To post C# code type the following: ```cs // code here ``` Get an example by typing $codegif in chat If your code is too long, post it to: https://paste.mod.gg/
N0b0dy
N0b0dyOP3y ago
The clients places orders (goods, items etc...) and then they have two options for the delivery such as standard, and Express. In standard, there are three steps Prepared, Dispatched, Delivered. the status of each step gets update after certain days. So, I want to design an architecture for both delivery system that can update the status of the post item automatically
public abstract class OrderTrackingContext
{
private OrderTrackingContext _context;

// Public properties common to all deliver class System
public DateTime orderDate { get; private set; }
public int orderId { get; private set; }
public string orderService { get; set; }

// Constructor
public OrderTrackingContext(DateTime orderDate, int orderId, string orderService)
{
this.orderDate = orderDate;
this.orderId = orderId;
this.orderService = orderService;
}

// A common methods
public abstract void deliveryDate(DateTime orderDate);

}
public abstract class OrderTrackingContext
{
private OrderTrackingContext _context;

// Public properties common to all deliver class System
public DateTime orderDate { get; private set; }
public int orderId { get; private set; }
public string orderService { get; set; }

// Constructor
public OrderTrackingContext(DateTime orderDate, int orderId, string orderService)
{
this.orderDate = orderDate;
this.orderId = orderId;
this.orderService = orderService;
}

// A common methods
public abstract void deliveryDate(DateTime orderDate);

}
this is my base class
Yawnder
Yawnder3y ago
Your OrderTrackingContext has an OrderTrackingContext..? "Is there any way that I can change these standPost status automatically, so the client get notification?" No, nothing is automatic, you have to code it.
N0b0dy
N0b0dyOP3y ago
@Yawnder-Tired of Authenticating I know How to code it update method is not public
麺麭
麺麭3y ago
So what are the steps of express? Do they exist yet?
Angius
Angius3y ago
To me, it seems like a simple case of
public class Tracking
{
public ShipmentType ShipmentType { get; set; }
public Status Status { get; set; }
public List<Item> Items { get; set; }
// ...
}
public class Tracking
{
public ShipmentType ShipmentType { get; set; }
public Status Status { get; set; }
public List<Item> Items { get; set; }
// ...
}
and just updating the Status when needed, in the controller or w/e
Yawnder
Yawnder3y ago
Right now, I don't get what you need help with tbh. You're saying a lot of things, but... it's not helping my comprehension of the issue you're having.
N0b0dy
N0b0dyOP3y ago
yes express has only two steps, dispatch and deliver
Angius
Angius3y ago
(as a side note, use PascalCase plz)
Yawnder
Yawnder3y ago
I think you need to reduce the problem to it's simplest expression.
N0b0dy
N0b0dyOP3y ago
@Yawnder-Tired of Authenticating ok
麺麭
麺麭3y ago
Yeah maybe I'd take a step back. I'm a fan of abstraction but it can make things confusing early on before you've solved the initial problem Is this a web app? Console app?
N0b0dy
N0b0dyOP3y ago
console app @aes
麺麭
麺麭3y ago
Is this just for testing or... like where will this be used?
N0b0dy
N0b0dyOP3y ago
For example, I am an owner of goods shop. My clients order some stuff and they want me to deliver them to you with guaranteed delivery date. So, I have two options for post Standard and express. this is the first step.
麺麭
麺麭3y ago
What are your inputs and outputs, and how often do you get and need them?
N0b0dy
N0b0dyOP3y ago
Inputs are OrderId, delivery type, and order Date. Now, I have create a base class. Outputs are delivery date with order Id. Now from the base class, Is it a good idea to Inherit the class to Express and standard class?
Angius
Angius3y ago
I'd just use an enum and a single class tbh
麺麭
麺麭3y ago
Yeah With an if statement or that state machine you were talking about
Yawnder
Yawnder3y ago
(and I still don't understand why OrderTrackingContext has an OrderTrackingContext in it.)
麺麭
麺麭3y ago
If using a base class becomes useful, it will become apparent as you write it
N0b0dy
N0b0dyOP3y ago
this is just test code.
Yawnder
Yawnder3y ago
No, I'm fine, but thanks for the offer.
麺麭
麺麭3y ago
How are delivery dates calculated? Aside from standard vs express, like what determines the exact date?
N0b0dy
N0b0dyOP3y ago
delivery dates will be calculate by adding days . For standard Prepared ( 2 days add from placed date), Dispatched (2 days from prepared), deliver (0.5 days) same with express but less days I am ok to write separate class for each delivery type. Is it a good approach?
麺麭
麺麭3y ago
Do you even need classes?
N0b0dy
N0b0dyOP3y ago
because in future, I want to change my prepared order time for to 3 days for s the standard delivery.
麺麭
麺麭3y ago
I would just create a console app that takes the inputs you want and gives you outputs you want using if statements and all that. Once you get it working, you can create classes
N0b0dy
N0b0dyOP3y ago
I was thinking to impalement a design pattern for each state of delivery type, So I can add more code in future if the policy changes for the delivery.
麺麭
麺麭3y ago
Because I imagine the harder problem will be deciding how to persist your data. Like what if your console app crashes. Do you lose all your orders? Or do you store your orders elsewhere and this is only used to calculate delivery dates. You can start thinking about classes then
N0b0dy
N0b0dyOP3y ago
my data is a small, not for a big scale. no need to worry about that. Now please give a map to implement class for the delivery system.
麺麭
麺麭3y ago
You can make interfaces or abstract classes for this. I'd just start simple before you start thinking about infrastructure
N0b0dy
N0b0dyOP3y ago
ok,
public interface IOrderState
{
void orderStatus(string status);
DateTime processedorder(DateTime orderDate);

}
public interface IOrderState
{
void orderStatus(string status);
DateTime processedorder(DateTime orderDate);

}
this is my interface, do i need more functions here?
Angius
Angius3y ago
You need them to be PascalCase if anything 😛
麺麭
麺麭3y ago
Does your current code work now?
Angius
Angius3y ago
Also, status seems like an enum kinda situation, not a string
麺麭
麺麭3y ago
Try to get it working for only standard. Then think about how to do it for express and what you'd need to change with your current code. You'll probably see how you should implement your abstract classes and interfaces then
N0b0dy
N0b0dyOP3y ago
no, I am still working on it. Not sure about the design map
麺麭
麺麭3y ago
What do you mean by design map?
N0b0dy
N0b0dyOP3y ago
that make sense. design map means, like architecture of the system. like design pattern
public enum StandardDeliveryState
{
Placed,
Prepared,
Dispatched,
Delivered,
}
public enum StandardDeliveryState
{
Placed,
Prepared,
Dispatched,
Delivered,
}
麺麭
麺麭3y ago
I like this. You can create a class or record from user input and fill these values with your inputs. Orderid and such. You could create a public method on Tracking called Process or MoveNext or something and make a private state machine on it. Calling this method would move the current state to the next state based on whether it's standard or express. I'm not 100% sure what your implementation would be since I don't know what exactly you need from this software you're making, but you could start with something like this. The idea is to start simple
Angius
Angius3y ago
Yep. Some sort of
Status = (Status, Type) switch {
(Status.Placed, Type.Standard) => Status.Prepared,
(Status.Prepared, Type.Standard) => Status.Dispatched,
(Status.Dispatched, Type.Standard) => Status.Delivered,
(Status.Placed, Type.Express) => Status.Delivered,
_ => Status.Placed
};
Status = (Status, Type) switch {
(Status.Placed, Type.Standard) => Status.Prepared,
(Status.Prepared, Type.Standard) => Status.Dispatched,
(Status.Dispatched, Type.Standard) => Status.Delivered,
(Status.Placed, Type.Express) => Status.Delivered,
_ => Status.Placed
};
or some such
N0b0dy
N0b0dyOP3y ago
ok, I will try your approach and paste my code here for review. How about that?
麺麭
麺麭3y ago
I'm down to look at anything, but the fastest way to iterate is to implement the absolute minimum of what you need to get something working and then test your app to see if it works Then add some more, then test And if you get errors or it's just not working, you can post about it here
N0b0dy
N0b0dyOP3y ago
sounds good to me, thanks sun warriors @aes @Angius hi I have implemented following interface
public interface IOrderState
{
DateTime PreparedOrder(DateTime orderDate);
DateTime DispatchOrder(DateTime preparedDate);
DateTime Delivered(DateTime dispatchDate);

}
public interface IOrderState
{
DateTime PreparedOrder(DateTime orderDate);
DateTime DispatchOrder(DateTime preparedDate);
DateTime Delivered(DateTime dispatchDate);

}
public enum StandardDeliveryState
{
Placed,
Prepared,
Dispatched,
Delivered,
}

public class StandardDeliveryContext: IOrderState
{
public static OrderRepository OrderRepository { get; set; }

public static void Init(OrderRepository _orderRepository)

{

OrderRepository = _orderRepository;

}


public int customerId { get; set; }

public int orderId { get; set; }

public DateTime placedOrderDate { get; set; }

private IOrderState process;

private StandardDeliveryState state;
public StandardDeliveryState State
{
get => state;
set
{
state = value;

switch (state)
{

case StandardDeliveryState.Placed:
process = new PreparedOrder(this);
break;

case StandardDeliveryState.Dispatched:
process = new DispatchOrder(this);
break;

case StandardDeliveryState.Delivered:
process = new Delivered(this);
break;
}
}
}

public void PreparedOrder(this)
{
process.PreparedOrder(placedOrderDate);
}

public void DispatchOrder(DateTime placedOrderDate)
{
process.DispatchOrder(placedOrderDate);
}
public void Delivered(DateTime placedOrderDate)
{
process.Delivered(placedOrderDate);
}
}
public enum StandardDeliveryState
{
Placed,
Prepared,
Dispatched,
Delivered,
}

public class StandardDeliveryContext: IOrderState
{
public static OrderRepository OrderRepository { get; set; }

public static void Init(OrderRepository _orderRepository)

{

OrderRepository = _orderRepository;

}


public int customerId { get; set; }

public int orderId { get; set; }

public DateTime placedOrderDate { get; set; }

private IOrderState process;

private StandardDeliveryState state;
public StandardDeliveryState State
{
get => state;
set
{
state = value;

switch (state)
{

case StandardDeliveryState.Placed:
process = new PreparedOrder(this);
break;

case StandardDeliveryState.Dispatched:
process = new DispatchOrder(this);
break;

case StandardDeliveryState.Delivered:
process = new Delivered(this);
break;
}
}
}

public void PreparedOrder(this)
{
process.PreparedOrder(placedOrderDate);
}

public void DispatchOrder(DateTime placedOrderDate)
{
process.DispatchOrder(placedOrderDate);
}
public void Delivered(DateTime placedOrderDate)
{
process.Delivered(placedOrderDate);
}
}
public class Prepared : DeliverySystem, IOrderState

{

private readonly StandardDeliveryContext standardDelivery;
public DateTime preparedDate { get; set; }


public Prepared(StandardDeliveryContext _standardDelivery) : base(_standardDelivery)

{

this.standardDelivery = _standardDelivery;

}


public DateTime PreparedOrder(DateTime placedOrderDate)
{
standardDelivery.State = StandardDeliveryState.Prepared;
// standardDelivery.placedOrderDate = standardDelivery.placedOrderDate.AddDays(1);
return placedOrderDate.AddDays(1);
}

public DateTime DispatchOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}


public DateTime DeliveredOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}
}
public class Prepared : DeliverySystem, IOrderState

{

private readonly StandardDeliveryContext standardDelivery;
public DateTime preparedDate { get; set; }


public Prepared(StandardDeliveryContext _standardDelivery) : base(_standardDelivery)

{

this.standardDelivery = _standardDelivery;

}


public DateTime PreparedOrder(DateTime placedOrderDate)
{
standardDelivery.State = StandardDeliveryState.Prepared;
// standardDelivery.placedOrderDate = standardDelivery.placedOrderDate.AddDays(1);
return placedOrderDate.AddDays(1);
}

public DateTime DispatchOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}


public DateTime DeliveredOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}
}
public class Dispatched : DeliverySystem, IOrderState

{

private readonly StandardDeliveryContext standardDelivery;
public DateTime dispatchDate { get; set; }


public Dispatched(StandardDeliveryContext _standardDelivery) : base(_standardDelivery)

{

this.standardDelivery = _standardDelivery;

}


public DateTime PreparedOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}

public DateTime DispatchOrder(DateTime placedOrderDate)
{
standardDelivery.State = StandardDeliveryState.Dispatched;
//standardDelivery.placedOrderDate = standardDelivery.placedOrderDate.AddDays(1);
return placedOrderDate.AddDays(1);
}
public DateTime DeliveredOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}
}
public class Dispatched : DeliverySystem, IOrderState

{

private readonly StandardDeliveryContext standardDelivery;
public DateTime dispatchDate { get; set; }


public Dispatched(StandardDeliveryContext _standardDelivery) : base(_standardDelivery)

{

this.standardDelivery = _standardDelivery;

}


public DateTime PreparedOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}

public DateTime DispatchOrder(DateTime placedOrderDate)
{
standardDelivery.State = StandardDeliveryState.Dispatched;
//standardDelivery.placedOrderDate = standardDelivery.placedOrderDate.AddDays(1);
return placedOrderDate.AddDays(1);
}
public DateTime DeliveredOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}
}
public class Delivered : DeliverySystem, IOrderState

{

private readonly StandardDeliveryContext standardDelivery;
public DateTime deliveryDate { get; set; }


public Delivered(StandardDeliveryContext _standardDelivery) : base(_standardDelivery)
{

this.standardDelivery = _standardDelivery;

}


public DateTime PreparedOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}

public DateTime DispatchOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}
public DateTime DeliveredOrder(DateTime placedOrderDate)
{
standardDelivery.State = StandardDeliveryState.Delivered;
// placedOrderDate = standardDelivery.placedOrderDate.AddDays(1);
return placedOrderDate.AddDays(1);
}
}
public class Delivered : DeliverySystem, IOrderState

{

private readonly StandardDeliveryContext standardDelivery;
public DateTime deliveryDate { get; set; }


public Delivered(StandardDeliveryContext _standardDelivery) : base(_standardDelivery)
{

this.standardDelivery = _standardDelivery;

}


public DateTime PreparedOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}

public DateTime DispatchOrder(DateTime placedOrderDate)
{
throw new NotImplementedException("Data");
}
public DateTime DeliveredOrder(DateTime placedOrderDate)
{
standardDelivery.State = StandardDeliveryState.Delivered;
// placedOrderDate = standardDelivery.placedOrderDate.AddDays(1);
return placedOrderDate.AddDays(1);
}
}
/// <summary>
/// The 'Base' abstract class
/// </summary>
public abstract class DeliverySystem

{

private StandardDeliveryContext standardDeliveryContext;

public DeliverySystem(StandardDeliveryContext _standardDeliveryContext)
{

this.standardDeliveryContext = _standardDeliveryContext;

}


}
/// <summary>
/// The 'Base' abstract class
/// </summary>
public abstract class DeliverySystem

{

private StandardDeliveryContext standardDeliveryContext;

public DeliverySystem(StandardDeliveryContext _standardDeliveryContext)
{

this.standardDeliveryContext = _standardDeliveryContext;

}


}
@aes please review my code
麺麭
麺麭3y ago
Does the code work for you? I think I see some type mismatches
N0b0dy
N0b0dyOP3y ago
No , does not but fixed these errors
Want results from more Discord servers?
Add your server