Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Design and Architecture
  4. Avoiding cycles with interfaces [modified]

Avoiding cycles with interfaces [modified]

Scheduled Pinned Locked Moved Design and Architecture
tutorialquestioncareer
7 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    Quake2Player
    wrote on last edited by
    #1

    Hello, I have a situation where I have a cycle: Group <>---- Contact ..........-----<> I have the class Contact which has name (eg. John), addr, etc. And the class Group which has a name (eg. Friends) and a list of contacts List<contact> The thing is that I want the Contact to know what groups contain him For example lets say I have the groups Family, Friends, Job and they all contain John (and others) I want that these groups contain John and that John knows he is member of these groups. I want to avoid the cycle, Should I use an Interface? or maybe other solution?

    modified on Wednesday, April 15, 2009 6:14 PM

    Q L K 3 Replies Last reply
    0
    • Q Quake2Player

      Hello, I have a situation where I have a cycle: Group <>---- Contact ..........-----<> I have the class Contact which has name (eg. John), addr, etc. And the class Group which has a name (eg. Friends) and a list of contacts List<contact> The thing is that I want the Contact to know what groups contain him For example lets say I have the groups Family, Friends, Job and they all contain John (and others) I want that these groups contain John and that John knows he is member of these groups. I want to avoid the cycle, Should I use an Interface? or maybe other solution?

      modified on Wednesday, April 15, 2009 6:14 PM

      Q Offline
      Q Offline
      Quake2Player
      wrote on last edited by
      #2

      come on... no one?

      1 Reply Last reply
      0
      • Q Quake2Player

        Hello, I have a situation where I have a cycle: Group <>---- Contact ..........-----<> I have the class Contact which has name (eg. John), addr, etc. And the class Group which has a name (eg. Friends) and a list of contacts List<contact> The thing is that I want the Contact to know what groups contain him For example lets say I have the groups Family, Friends, Job and they all contain John (and others) I want that these groups contain John and that John knows he is member of these groups. I want to avoid the cycle, Should I use an Interface? or maybe other solution?

        modified on Wednesday, April 15, 2009 6:14 PM

        L Offline
        L Offline
        Luc Pattyn
        wrote on last edited by
        #3

        I don't see the problem. A Group holds zero, one or more Contacts. and each Contact wants to hold a list of all the Groups it belongs to. So a Group either *is* a list, or *contains* a list. and a Contact contains a list. IIRC that is called aggregation: putting information (list of Groups) in members of the class (Contact). Refinement: I didn't provide type information for the lists; it could be that: a Group either *is* a list, or *contains* a list of Contacts. and a Contact contains a list of Groups. or you could define a common ancestor for Group and Contact, and use that type as the type held in both lists (Inheritance). Conclusion: I don't need interfaces to "break" the cycle, there wasn't really a cycle if you ask me. If you insist on having an interface, how about IListable; both Group and Contact implement IListable (not sure what the functionality would be though); and both lists could contain IListables. :)

        Luc Pattyn [Forum Guidelines] [My Articles]


        Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in


        Q 1 Reply Last reply
        0
        • L Luc Pattyn

          I don't see the problem. A Group holds zero, one or more Contacts. and each Contact wants to hold a list of all the Groups it belongs to. So a Group either *is* a list, or *contains* a list. and a Contact contains a list. IIRC that is called aggregation: putting information (list of Groups) in members of the class (Contact). Refinement: I didn't provide type information for the lists; it could be that: a Group either *is* a list, or *contains* a list of Contacts. and a Contact contains a list of Groups. or you could define a common ancestor for Group and Contact, and use that type as the type held in both lists (Inheritance). Conclusion: I don't need interfaces to "break" the cycle, there wasn't really a cycle if you ask me. If you insist on having an interface, how about IListable; both Group and Contact implement IListable (not sure what the functionality would be though); and both lists could contain IListables. :)

          Luc Pattyn [Forum Guidelines] [My Articles]


          Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in


          Q Offline
          Q Offline
          Quake2Player
          wrote on last edited by
          #4

          Hi, thanks for replying!.. "there wasn't really a cycle if you ask me." The cycle is between Contact and Group.. We've been told in University that we have to avoid these cycles because of dependency and coupling (which I don't see but was hoping that someone here could tell me).. An example where I can see the solution more clearly is for example a Car that contains an Engine, and the Engine must notify the Car that contains him something.. One solution, the one I have to avoid is: Car contains Engine, Engine contains Car In that case one would put an interface ISomething (Car : ISomething) and the Engine instead of having a Car would have an ISomething The difference might be that the Engine must do something on the Car (turn it on for example). And here, the contact doesnt have to do anything on the group and viceversa. Am i right? Should i go with the cycle anyway?

          L C 2 Replies Last reply
          0
          • Q Quake2Player

            Hi, thanks for replying!.. "there wasn't really a cycle if you ask me." The cycle is between Contact and Group.. We've been told in University that we have to avoid these cycles because of dependency and coupling (which I don't see but was hoping that someone here could tell me).. An example where I can see the solution more clearly is for example a Car that contains an Engine, and the Engine must notify the Car that contains him something.. One solution, the one I have to avoid is: Car contains Engine, Engine contains Car In that case one would put an interface ISomething (Car : ISomething) and the Engine instead of having a Car would have an ISomething The difference might be that the Engine must do something on the Car (turn it on for example). And here, the contact doesnt have to do anything on the group and viceversa. Am i right? Should i go with the cycle anyway?

            L Offline
            L Offline
            Luc Pattyn
            wrote on last edited by
            #5

            In the car-engine situation, I would do: car contains an engine, and is fully aware of its functionality, not its internals of course. engine knows nothing about cars, but holds one or more public events (.NET speak), where an event is a list of delegates, a delegate basically is a function pointer or a callback. So the car tells the engine it is interested in some events; the car engine signals those occurrences through the appropriate event, without knowing anything about the subscriber(s); all it knows is the syntax of the delegate (number and type of parameters, there normally is no return value). Again no interface is involved; although you could achieve the same with an interface (your ISomething, I would say IAmInterestedInSomeEngineStuff). The advantage of events is they can hold and serve multiple listeners without the engine even being aware of that. :)

            Luc Pattyn [Forum Guidelines] [My Articles]


            Avoiding unwanted divs (as in "articles needing approval") with the help of this FireFox add-in


            modified on Thursday, April 16, 2009 11:06 PM

            1 Reply Last reply
            0
            • Q Quake2Player

              Hi, thanks for replying!.. "there wasn't really a cycle if you ask me." The cycle is between Contact and Group.. We've been told in University that we have to avoid these cycles because of dependency and coupling (which I don't see but was hoping that someone here could tell me).. An example where I can see the solution more clearly is for example a Car that contains an Engine, and the Engine must notify the Car that contains him something.. One solution, the one I have to avoid is: Car contains Engine, Engine contains Car In that case one would put an interface ISomething (Car : ISomething) and the Engine instead of having a Car would have an ISomething The difference might be that the Engine must do something on the Car (turn it on for example). And here, the contact doesnt have to do anything on the group and viceversa. Am i right? Should i go with the cycle anyway?

              C Offline
              C Offline
              CodingYoshi
              wrote on last edited by
              #6

              In my opinion, also if you ask your profs, you should avoid cyclic dependencies between assemblies but not between classes. You should try to minimize coupling but you can not avoid it altogether. Afterall, the classes need to communicate with each other to accomplish whatever needs to be accomplished. You can create an interface and you can always do so but remember you still have a cyclic dependency but it is less direct. Now you are tied to something which implements the interface. If you never want to allow contact creation without group, then do not allow its creation unless from within the group: Contact c = aGroup.NewContact() and Group will call contact's constructor. Cyclic dependency is bad between assemblies because of compilation race.

              CodingYoshi Visual Basic is for basic people, C# is for sharp people. Farid Tarin '07

              1 Reply Last reply
              0
              • Q Quake2Player

                Hello, I have a situation where I have a cycle: Group <>---- Contact ..........-----<> I have the class Contact which has name (eg. John), addr, etc. And the class Group which has a name (eg. Friends) and a list of contacts List<contact> The thing is that I want the Contact to know what groups contain him For example lets say I have the groups Family, Friends, Job and they all contain John (and others) I want that these groups contain John and that John knows he is member of these groups. I want to avoid the cycle, Should I use an Interface? or maybe other solution?

                modified on Wednesday, April 15, 2009 6:14 PM

                K Offline
                K Offline
                Keld Olykke
                wrote on last edited by
                #7

                Interesting topic. It is very frustrating when interfaces express very complicated dependencies between objects. Cyclic dependencies may result in endless loops and weird state control. An interface specifies a unidirectional 'control panel': You can use it to push and pull, but you have the initiative and don't want be interrupted while using the interface. However, if cycles exist between interfaces (or between objects), you may be interrupted each time you try to operate a certain object via an interface. If this happens a lot, you have spaghetti code. Our world is full of interconnected objects that control each others, so what to do about these when modeling them in software? A very simple example is a Nut and a Bolt. Sometimes the Nut turns the Bolt and sometimes the Bolt turns the Nut. Lets say an interface for both Nut and Bolt is ITurnable and it contains a turn(float angle) method. No interface cycle exists. Now, if Bolt is turned, it decides whether an attached Nut should be turned or not. Likewise, if Nut is turned, it decides whether an inserted Bolt should be turned or not. These decisions are implementation specific, and it may be that Nut and Bolt call each other recursively, but the ITurnable interface is clear about direction of control. Yes, I know. The Bolt and Nut need to be connected, if they should know something about each other e.g. friction, or if they should be able to turn each other; how could that be expressed with interfaces? A) Interface for a made up object. You can make a fictional interface that ties a Nut and a Bolt e.g. an IConnection implemented by a 3rd class e.g. Connection. If a Nut actively unscrews itself, it will direct control to the IConnection implementor that is responsible for letting the Bolt know. B) Interface for existing objects. You can implement an attach/detach interface for Nut and Bolt e.g. IConnector implemented in both classes. This interface could just have an attach(IConnector connector) and a detach(IConnector connector) method. Again the direction of control is clear, and it is specified via IConnector that Nut and Bolt can be interconnected. C) Interfaces for existing objects. You can implement attach/detach in interfaces of Nut and Bolt e.g. INut and IBolt, respectively. INut could have an attach(IBolt bolt) and a

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups