Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Added new idea
Source Link

EDIT2: So it is clear that the class hierarchy here is a bit overdone. To simplify it, I could do

abstract class SenderReceiver {
    Socket _Socket;
    protected class StateObject { /* For async network methods */ }
    void Dispose();
    void Exit();
}
class SenderReceiverTcp : SenderReceiver {
    void Connect() { /* Sets up socket and calls BeginConnect */ }
    void EndConnect() { /* Callback for Connect() */ }
    
    void Accept() { /* Sets up socket, Bind, Listen, BeginAccept */ }
    void EndAccept() { /* Callback for Accept() */ }
    
    void Send(msg) { /* Send message */ }
    void Receive() { /* Receive or BeginReceive */ }
    void EndReceive() { /* Callback if Receive is async */ }
}

class SenderReceiverUdp : SenderReceiver {
    void Connect() { /* Sets up socket and calls Bind */ }
    
    void Send(msg) { /* Send message */ }
    void Receive() { /* Receive or BeginReceive */ }
    void EndReceive() { /* Callback if Receive is async */ }
}

class SenderRecevierD1 {
    SenderReceiverTcp _SenderReceiverTcp;
    
    void Connect() { _SenderReceiverTcp.Connect(); }
    void Accept() { _SenderReceiverTcp.Accept(); }
    void Send() { msg.Create(); _SenderReceiverTcp.Send(msg); }
    ...
}

class SenderReceiverD2 {
    SenderReceiverUdp _SenderReceiverUdp;
    
    void Connect() { _SenderReceiverUdp.Connect(); }
    void Send() { msg.Create(); _SenderReceiverUdp.Send(msg);
                _SenderReceiverUdp.Receive();
                if (!_SenderReceiverUdp.ReceiveEnded()) // Check for ack
                    _SenderReceiverUdp.Send(msg);
                }
    ...
}

This way, the D# classes don't need to know how to send messages for their type (maybe one D class with TCP retries if there is no acknowledgement while another doesn't wait for an acknowledgement because that D type doesn't send acknowledgements) but the differences in TCP/UDP setup and send are abstracted in the SenderReceiverTcp/Udp classes.

This is sort of an extension of "Removing SenderReceiver from the base class". I don't want to post this as an answer because I'm not positive if it's maximally right. I'll leave it for a bit and wait for community feedback.

EDIT2: So it is clear that the class hierarchy here is a bit overdone. To simplify it, I could do

abstract class SenderReceiver {
    Socket _Socket;
    protected class StateObject { /* For async network methods */ }
    void Dispose();
    void Exit();
}
class SenderReceiverTcp : SenderReceiver {
    void Connect() { /* Sets up socket and calls BeginConnect */ }
    void EndConnect() { /* Callback for Connect() */ }
    
    void Accept() { /* Sets up socket, Bind, Listen, BeginAccept */ }
    void EndAccept() { /* Callback for Accept() */ }
    
    void Send(msg) { /* Send message */ }
    void Receive() { /* Receive or BeginReceive */ }
    void EndReceive() { /* Callback if Receive is async */ }
}

class SenderReceiverUdp : SenderReceiver {
    void Connect() { /* Sets up socket and calls Bind */ }
    
    void Send(msg) { /* Send message */ }
    void Receive() { /* Receive or BeginReceive */ }
    void EndReceive() { /* Callback if Receive is async */ }
}

class SenderRecevierD1 {
    SenderReceiverTcp _SenderReceiverTcp;
    
    void Connect() { _SenderReceiverTcp.Connect(); }
    void Accept() { _SenderReceiverTcp.Accept(); }
    void Send() { msg.Create(); _SenderReceiverTcp.Send(msg); }
    ...
}

class SenderReceiverD2 {
    SenderReceiverUdp _SenderReceiverUdp;
    
    void Connect() { _SenderReceiverUdp.Connect(); }
    void Send() { msg.Create(); _SenderReceiverUdp.Send(msg);
                _SenderReceiverUdp.Receive();
                if (!_SenderReceiverUdp.ReceiveEnded()) // Check for ack
                    _SenderReceiverUdp.Send(msg);
                }
    ...
}

This way, the D# classes don't need to know how to send messages for their type (maybe one D class with TCP retries if there is no acknowledgement while another doesn't wait for an acknowledgement because that D type doesn't send acknowledgements) but the differences in TCP/UDP setup and send are abstracted in the SenderReceiverTcp/Udp classes.

This is sort of an extension of "Removing SenderReceiver from the base class". I don't want to post this as an answer because I'm not positive if it's maximally right. I'll leave it for a bit and wait for community feedback.

Added more code to show current attempts at flexibility. Removed newlines to shorten.
Source Link

Let's say there are SenderReceiver classes SenderReceiverD1, SenderReceiverD2, etc. describing different ways of communicating for each D1, D2, etc.:

abstract class SenderReceiver {
    abstract void Setup();
    abstract void SendA();
    public void CloseM1() { /* CodeCommon code */ }
    ...
    public void MN() { /* Common code */ }
}

abstract class SenderReceiverPlus : SenderReceiver {
    abstract void SendB();
}

class SenderReceiverD1SenderReceiverPlusTcp : SenderReceiverPlus {
    override void Setup() { /* BeginConnect code */ }
}

class SenderReceiverTcp : SenderReceiver {
    override void Setup() { /* Same code as above (vomit) */ }
}

class SenderReceiverPlusTcpD1 : SenderReceiverPlusTcp {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverD2SenderReceiverTcpD2 : SenderReceiverTcp {
    override void SendA()  { /* Code */ }
}

class SenderReceiverPlusUdp : SenderReceiverPlus {
    override void Setup() { /* Socket bind code */ }
}

class SenderReceiverUdp : SenderReceiver {
    override void Setup() { /* Same code as above (vomit) */ }
}

class SenderReceiverPlusUdpD3 : SenderReceiverPlusUdp {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverUdpD4 : SenderReceiverUdp {
    override void SendA()  { /* Code */ }
}

abstract class D {
    SenderReceiver S;
    abstract void DoThing();
}

class D1 : D {
    D1 () { S = new SenderReceiverD1SenderReceiverPlusTcpD1(); }
 
    override void DoThing() {
      S.SendA(); S.SendB(); S.SendAM1(); }
}

class D2 : D {
    D2 () { S.SendB = new SenderReceiverTcpD2(); }
    override void DoThing() { S.CloseSendA();
   S.M1(); }
}

class D2D3 : D {
    D2D1 () { S = new SenderReceiverD2SenderReceiverPlusUdpD3(); }
 
    override void DoThing() { S.SendA(); S.SendB(); S.M1(); }
}

class D4 : D {
    D2 () { S.SendA = new SenderReceiverUdpD4(); }
    override void DoThing() { S.CloseSendA();
   S.M1(); }
}
class Controller {
    List<D> ds;

    public Controller() {
        ds = new List<D>();
      new [] ds.Add({new D1());
    , new D2(), new ds.AddD3(), new D2D4()});
    }

    public DoAllThings() {
        foreach (D d in ds) {
            d.DoThing();
        }
    }
}

This does not work because (for one) D1's reference to S references a SenderReceiver and so SendB() is not assuredly there. Also, it's gross and there's duplicated code in the different Tcp and Udp types.

Is there a better way to do this?

EDIT:

Updated code to show attempts in current code at flexibility for Udp/Tcp protocols.

Let's say there are SenderReceiver classes SenderReceiverD1, SenderReceiverD2, etc. describing different ways of communicating for each D1, D2, etc.:

abstract class SenderReceiver {
    abstract void SendA();
    public void Close() { /* Code */ }
}

abstract class SenderReceiverPlus : SenderReceiver {
    abstract void SendB();
}

class SenderReceiverD1 : SenderReceiverPlus {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverD2 : SenderReceiver {
    override void SendA()  { /* Code */ }
}

abstract class D {
    SenderReceiver S;
    abstract void DoThing();
}

class D1 : D {
    D1 () { S = new SenderReceiverD1(); }
 
    override void DoThing() {
        S.SendA();
        S.SendB();
        S.Close();
    }
}

class D2 : D {
    D2 () { S = new SenderReceiverD2(); }
 
    override void DoThing() {
        S.SendA();
        S.Close();
    }
}
class Controller {
    List<D> ds;

    public Controller() {
        ds = new List<D>();
        ds.Add(new D1());
        ds.Add(new D2());
    }

    public DoAllThings() {
        foreach (D d in ds) {
            d.DoThing();
        }
    }
}

This does not work because D1's reference to S references a SenderReceiver and so SendB() is not assuredly there.

Is there a better way to do this?

Let's say there are SenderReceiver classes describing different ways of communicating for each D1, D2, etc.:

abstract class SenderReceiver {
    abstract void Setup();
    abstract void SendA();
    public void M1() { /* Common code */ }
    ...
    public void MN() { /* Common code */ }
}

abstract class SenderReceiverPlus : SenderReceiver {
    abstract void SendB();
}

class SenderReceiverPlusTcp : SenderReceiverPlus {
    override void Setup() { /* BeginConnect code */ }
}

class SenderReceiverTcp : SenderReceiver {
    override void Setup() { /* Same code as above (vomit) */ }
}

class SenderReceiverPlusTcpD1 : SenderReceiverPlusTcp {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverTcpD2 : SenderReceiverTcp {
    override void SendA()  { /* Code */ }
}

class SenderReceiverPlusUdp : SenderReceiverPlus {
    override void Setup() { /* Socket bind code */ }
}

class SenderReceiverUdp : SenderReceiver {
    override void Setup() { /* Same code as above (vomit) */ }
}

class SenderReceiverPlusUdpD3 : SenderReceiverPlusUdp {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverUdpD4 : SenderReceiverUdp {
    override void SendA()  { /* Code */ }
}

abstract class D {
    SenderReceiver S;
    abstract void DoThing();
}

class D1 : D {
    D1 () { S = new SenderReceiverPlusTcpD1(); }
    override void DoThing() { S.SendA(); S.SendB(); S.M1(); }
}

class D2 : D {
    D2 () { S = new SenderReceiverTcpD2(); }
    override void DoThing() { S.SendA(); S.M1(); }
}

class D3 : D {
    D1 () { S = new SenderReceiverPlusUdpD3(); }
    override void DoThing() { S.SendA(); S.SendB(); S.M1(); }
}

class D4 : D {
    D2 () { S = new SenderReceiverUdpD4(); }
    override void DoThing() { S.SendA(); S.M1(); }
}
class Controller {
    List<D> ds;

    public Controller() {
        ds = new List<D>(new [] {new D1(), new D2(), new D3(), new D4()});
    }

    public DoAllThings() {
        foreach (D d in ds) {
            d.DoThing();
        }
    }
}

This does not work because (for one) D1's reference to S references a SenderReceiver and so SendB() is not assuredly there. Also, it's gross and there's duplicated code in the different Tcp and Udp types.

Is there a better way to do this?

EDIT:

Updated code to show attempts in current code at flexibility for Udp/Tcp protocols.

added 8 characters in body
Source Link

Let's say there are classes D1, D2, etc. describing different types of an abstract class D.

Let's say there are SenderReceiver classes SenderReceiverD1, SenderReceiverD2, etc. describing different ways of communicating for each D1, D2, etc.:

abstract class SenderReceiver {
    abstract void SendA();
    public void Close() { /* Code */ }
}

abstract class SenderReceiverPlus : SenderReceiver {
    abstract void SendB();
}

class SenderReceiverD1 : SenderReceiverPlus {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverD2 : SenderReceiver {
    override void SendA()  { /* Code */ }
}

abstract class D {
    SenderReceiver S;
    abstract void DoThing();
}

class D1 : D {
    D1 () { S = new SenderReceiverD1(); }

    override void DoThing() {
        S.SendA();
        S.SendB();
        S.Close();
    }
}

class D2 : D {
    D2 () { S = new SenderReceiverD2(); }

    override void DoThing() {
        S.SendA();
        S.Close();
    }
}

And there is a class with a list of D objects:

class Controller {
    List<D> ds;

    public Controller() {
        ds = new List<D>();
        ds.Add(new D1());
        ds.Add(new D2());
    }

    public DoAllThings() {
        foreach (D d in ds) {
            d.DoThing();
        }
    }
}

This does not work because D1's reference to S references a SenderReceiver and so SendB() is not assuredly there.

I've considered empty virtual methods in the base class, casting S to the correct type in D1 and D2, and not having S in the D class. None of these are particularly satisfying.

Is there a better way to do this?

Let's say there are classes D1, D2, etc. describing different types of an abstract class D.

Let's say there are SenderReceiver classes SenderReceiverD1, SenderReceiverD2, etc. describing different ways of communicating for each D1, D2, etc.:

abstract class SenderReceiver {
    abstract void SendA();
    public void Close() { /* Code */ }
}

abstract class SenderReceiverPlus : SenderReceiver {
    abstract void SendB();
}

class SenderReceiverD1 : SenderReceiverPlus {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverD2 : SenderReceiver {
    override void SendA()  { /* Code */ }
}

abstract class D {
    SenderReceiver S;
    abstract void DoThing();
}

class D1 {
    D1 () { S = new SenderReceiverD1(); }

    override void DoThing() {
        S.SendA();
        S.SendB();
        S.Close();
    }
}

class D2 {
    D2 () { S = new SenderReceiverD2(); }

    override void DoThing() {
        S.SendA();
        S.Close();
    }
}

And there is a class with a list of D objects:

class Controller {
    List<D> ds;

    public Controller() {
        ds = new List<D>();
        ds.Add(new D1());
        ds.Add(new D2());
    }

    public DoAllThings() {
        foreach (D d in ds) {
            d.DoThing();
        }
    }
}

This does not work because D1's reference to S references a SenderReceiver and so SendB() is not assuredly there.

I've considered empty virtual methods in the base class, casting S to the correct type in D1 and D2, and not having S in the D class. None of these are particularly satisfying.

Is there a better way to do this?

Let's say there are classes D1, D2, etc. describing different types of an abstract class D.

Let's say there are SenderReceiver classes SenderReceiverD1, SenderReceiverD2, etc. describing different ways of communicating for each D1, D2, etc.:

abstract class SenderReceiver {
    abstract void SendA();
    public void Close() { /* Code */ }
}

abstract class SenderReceiverPlus : SenderReceiver {
    abstract void SendB();
}

class SenderReceiverD1 : SenderReceiverPlus {
    override void SendA()  { /* Code */ }
    override void SendB()  { /* Code */ }
}

class SenderReceiverD2 : SenderReceiver {
    override void SendA()  { /* Code */ }
}

abstract class D {
    SenderReceiver S;
    abstract void DoThing();
}

class D1 : D {
    D1 () { S = new SenderReceiverD1(); }

    override void DoThing() {
        S.SendA();
        S.SendB();
        S.Close();
    }
}

class D2 : D {
    D2 () { S = new SenderReceiverD2(); }

    override void DoThing() {
        S.SendA();
        S.Close();
    }
}

And there is a class with a list of D objects:

class Controller {
    List<D> ds;

    public Controller() {
        ds = new List<D>();
        ds.Add(new D1());
        ds.Add(new D2());
    }

    public DoAllThings() {
        foreach (D d in ds) {
            d.DoThing();
        }
    }
}

This does not work because D1's reference to S references a SenderReceiver and so SendB() is not assuredly there.

I've considered empty virtual methods in the base class, casting S to the correct type in D1 and D2, and not having S in the D class. None of these are particularly satisfying.

Is there a better way to do this?

Added more code to express problem. Removed newlines to shorten page.
Source Link
Loading
Source Link
Loading