Thread: Commands as an enum

Page 5 of 7 FirstFirst ... 34567 LastLast
Results 41 to 50 of 64
  1. #41  




    Scu11's Avatar
    Join Date
    Aug 2007
    Age
    25
    Posts
    15,988
    Thanks given
    7,022
    Thanks received
    11,586
    Rep Power
    5000
    Quote Originally Posted by kierandevvs View Post
    This breaks the SOLID principle: open close, use the strategy pattern to segregate responsibilities and ensure code change isn't required for code extension.
    using an enum has nothing to do with the open/close principal, you wouldn't model commands as inherently "open" classes - they aren't designed for extendability.




    Reply With Quote  
     

  2. #42  
    ???

    funkE's Avatar
    Join Date
    Feb 2008
    Posts
    2,597
    Thanks given
    234
    Thanks received
    965
    Rep Power
    1242
    I think you should really research "software design patterns" and imagine how they could be used in place of an enum...

    Not that I'd design commands this way... But...

    Even a class implementing an interface with access restrictions that are defined by an annotation that has a runtime retention policy is better IMO.
    .
    Reply With Quote  
     

  3. Thankful user:


  4. #43  
    Registered Member

    Join Date
    Jul 2013
    Posts
    106
    Thanks given
    7
    Thanks received
    48
    Rep Power
    84
    Quote Originally Posted by Scu11 View Post
    using an enum has nothing to do with the open/close principal, you wouldn't model commands as inherently "open" classes - they aren't designed for extendability.
    O/C has nothing to do with inheritance. A class should be "open for extension" (you can add new members) but "closed for modification" (cant modify the contract of currently published members).

    In simple terms, you can add behaviors, but you can't modify existing behaviors. Enums are canidates of violating O/C, as enums are objects whom have members which should abide by a contract - a contract that can be extended, but not modified.
    Reply With Quote  
     

  5. #44  
    Registered Member
    Greg's Avatar
    Join Date
    Jun 2010
    Posts
    996
    Thanks given
    161
    Thanks received
    446
    Rep Power
    718
    Quote Originally Posted by Scu11 View Post
    using an enum has nothing to do with the open/close principal, you wouldn't model commands as inherently "open" classes - they aren't designed for extendability.
    Quote Originally Posted by Serious ipwxy View Post
    O/C has nothing to do with inheritance. A class should be "open for extension" (you can add new members) but "closed for modification" (cant modify the contract of currently published members).

    In simple terms, you can add behaviors, but you can't modify existing behaviors. Enums are canidates of violating O/C, as enums are objects whom have members which should abide by a contract - a contract that can be extended, but not modified.
    "Inherently"

    Enums don't violate O/C because they're static and can't be inherited from so O/C can't apply
    [Only registered and activated users can see links. ]
    And as Scu pointed out, commands don't need to be extendable so O/C doesn't need to be followed, SOLID is a guideline not scripture
    Reply With Quote  
     

  6. Thankful users:


  7. #45  




    Scu11's Avatar
    Join Date
    Aug 2007
    Age
    25
    Posts
    15,988
    Thanks given
    7,022
    Thanks received
    11,586
    Rep Power
    5000
    Quote Originally Posted by Serious ipwxy View Post
    O/C has nothing to do with inheritance.
    O/C was underpinned by inheritance in OO languages when it was popularised.

    "Meyer's proposed solution to this dilemma relied on the notion of object-oriented inheritance (specifically implementation inheritance)"
    - [Only registered and activated users can see links. ]

    also, i said "inherently open classes", i wasn't specifically talking about inheritance. my fundamental point is that it doesn't make sends to design commands to be "open for extension".



    Quote Originally Posted by Serious ipwxy View Post
    A class should be "open for extension" (you can add new members) but "closed for modification" (cant modify the contract of currently published members).
    how are you proposing to "add new members" without inheritance?


    Quote Originally Posted by Serious ipwxy View Post
    Enums are canidates of violating O/C, as enums are objects whom have members which should abide by a contract - a contract that can be extended, but not modified.
    how can you extend the contract without modifying the underlying enum itself?




    Reply With Quote  
     

  8. #46  
    Registered Member

    Join Date
    Jul 2013
    Posts
    106
    Thanks given
    7
    Thanks received
    48
    Rep Power
    84
    Quote Originally Posted by Scu11 View Post
    O/C was underpinned by inheritance in OO languages when it was popularised.

    "Meyer's proposed solution to this dilemma relied on the notion of object-oriented inheritance (specifically implementation inheritance)"
    - [Only registered and activated users can see links. ]

    also, i said "inherently open classes", i wasn't specifically talking about inheritance. my fundamental point is that it doesn't make sends to design commands to be "open for extension".





    how are you proposing to "add new members" without inheritance?




    how can you extend the contract without modifying the underlying enum itself?
    By adding new members. O/C allows us to scale without worrying about modifying contracts for already published code, as clients may already depend on the contract in place.

    An enum could violate O/C by modifying existing behaviors in a way that violates the contract initially set; changing the behavior of an existing method will violate O/C.

    For example:

    Code:
    enum Printer {
        GET;
    
        /**
          *    Prints all string values from the array, delimiting with a space.
          */
        public void printAll(List<String> strings) {
            StringBuilder builder = new StringBuilder();
            strings.forEach(s -> builder.append(s).append(' '));
            System.out.println(builder);
        }
    }
    A client would use this:

    Code:
    Demo.GET.printAll(Arrays.asList("this", "is", "a", "demo"));
    After a few runs, clients can assume behaviors: printAll will always give a result which has a trailing whitespace, since it adds a space even after the last element. Clients will always expect it to work this way, and their code will depend on it always working this way.

    I could violate O/C by adding code which removes the trailing whitespace.

    Code:
    StringBuilder builder = new StringBuilder();
    strings.forEach(s -> builder.append(s).append(' '));
    builder.setLength(builder.length() - 1);
    System.out.println(builder);
    The enum type now violates O/C, since clients already depend on this code, and changing the semantics could affect their program undesirably. Even if Demo was derivable, overriding printAll to remove the trailing space would violate LSP. The solution would be to add a new member:

    Code:
    public void printAll(List<String> strings) { ... }
    public void printAllTrimmed(List<String> strings) { ... }
    This doesn't violate O/C, as we didn't modify, we extended. We keep existing code closed from modification, but leave the type open to extension. For more insight: [Only registered and activated users can see links. ] (answer I wrote a couple years ago)

    Saying "O/C has nothing to do with inheritance" isn't completely correct, as it's one of the ways to extend functionality without violating SRP. What I meant was, it's not the core of the principle, as with or without inheritance, the principle can be abided or violated.

    Beyond this, specific enum objects can actually derive from their base contract, violating principles such as LSP, which focus primarily on derivation:

    Code:
    enum Demo {
        FIRST,
        SECOND {
            @Override
            public void printAll(List<String> strings) {
                System.out.println("I violate LSP");
            }
        };
    
        public void printAll(List<String> strings) {
            strings.forEach(System.out::println);
        }
    }
    These principles exist to solve common problems. Preventing modification of existing contracts is the problem O/C attempts to solve. Enums are canidates for falling victim to this issue.

    Quote Originally Posted by Greg View Post
    "Inherently"

    Enums don't violate O/C because they're static and can't be inherited from so O/C can't apply
    [Only registered and activated users can see links. ]
    And as Scu pointed out, commands don't need to be extendable so O/C doesn't need to be followed, SOLID is a guideline not scripture
    OCP doesn't mean that all of the classes and methods can be extended, but rather that a conscientious developer makes informed decisions about where to put those extension points.
    In the case of an Enum a developer understands that there's no need to extend the possible values ... So he/she decides to completely close the class and not provide extension points
    "Cannot specify any more [enum object] values" is their idea of closing the type, most likely assuming the enums are used similar to primitives (switched upon). They don't account for the potential behaviors which the enum may perform, or how the type (not the values) can be scaled if needed, which is what O/C focuses on: behaviors & types, not the values (instantiated objects) of said types.

    Another reason why I think Enums don't violate OCP
    Keep in mind, as a contributor, there's a lot of assumpsions on SO; just because this was the first search result on Google doesn't mean it's biblical. There are books out there on this stuff, written by reliable sources whom have practiced and proven this on the field time and time again. If the question wasn't closed for being opinion based (would have lasted longer on SE exchange), I'd write an answer similar to this post.

    And I understand principles are not law, I was just stating that you can violate O/C by modifying the contract of existing code. You don't need class-based inheritance for O/C to be an concern.
    Reply With Quote  
     

  9. #47  
    Registered Member
    Greg's Avatar
    Join Date
    Jun 2010
    Posts
    996
    Thanks given
    161
    Thanks received
    446
    Rep Power
    718
    Quote Originally Posted by Serious ipwxy View Post
    Code:
    enum Printer {
        GET;
    
        /**
          *    Prints all string values from the array, delimiting with a space.
          */
        public void printAll(List<String> strings) {
            StringBuilder builder = new StringBuilder();
            strings.forEach(s -> builder.append(s).append(' '));
            System.out.println(builder);
        }
    }
    Code:
    enum Demo {
        FIRST,
        SECOND {
            @Override
            public void printAll(List<String> strings) {
                System.out.println("I violate LSP");
            }
        };
    
        public void printAll(List<String> strings) {
            strings.forEach(System.out::println);
        }
    }
    If you're following SOLID your examples break SRP before O/C should even be considered, and they still use inheritance to violate O/C.
    Reply With Quote  
     

  10. #48  
    Registered Member

    Join Date
    Jul 2013
    Posts
    106
    Thanks given
    7
    Thanks received
    48
    Rep Power
    84
    Quote Originally Posted by Greg View Post
    If you're following SOLID your examples break SRP before O/C should even be considered, and they still use inheritance to violate O/C.
    First example uses no inheritance, not sure where you see that. Are you talking about the use of dependency inversion (using List)? If so, that's not the focus point.

    Second example isn't an example of an O/C violation, it's an example of violating LSP, to show how even though enums are viewed as "non-derivable", they can violate principles that rely on subtyping. Feels like you didn't even read my post.

    I didn't enforce all SOLID principles in my example, as it'll only add complexity to a situation that, for some reason, is being made faaaaaar more complex than it actually is; no reason to, other than maybe proving myself?

    O/C aims to avoid modifying code which clients already rely on. It's an extremely simple concept. That doesn't mean you must extend the class to add new functionality; inheritance is only one out of a group of solutions. The strategy pattern is actually one of the more common solutions to avoiding O/C violations, as it's better to prefer composition over inheritance - you don't extend the class to add functionality, rather expose new strategies to the clients.
    Reply With Quote  
     

  11. #49  
    Extreme Donator
    EEAZY's Avatar
    Join Date
    Jul 2018
    Posts
    126
    Thanks given
    34
    Thanks received
    7
    Rep Power
    6
    Seems like a lot of wasted time IMO, could use cases...

    Edit: Read all the comments late, but this was already suggested.
    Last edited by EEAZY; 02-16-2019 at 06:10 AM. Reason: Too late to the party of trolls
    Reply With Quote  
     

  12. #50  
    Registered Member
    Greg's Avatar
    Join Date
    Jun 2010
    Posts
    996
    Thanks given
    161
    Thanks received
    446
    Rep Power
    718
    Quote Originally Posted by Serious ipwxy View Post
    First example uses no inheritance, not sure where you see that. Are you talking about the use of dependency inversion (using List)? If so, that's not the focus point.

    Second example isn't an example of an O/C violation, it's an example of violating LSP, to show how even though enums are viewed as "non-derivable", they can violate principles that rely on subtyping. Feels like you didn't even read my post.

    I didn't enforce all SOLID principles in my example, as it'll only add complexity to a situation that, for some reason, is being made faaaaaar more complex than it actually is; no reason to, other than maybe proving myself?

    O/C aims to avoid modifying code which clients already rely on. It's an extremely simple concept. That doesn't mean you must extend the class to add new functionality; inheritance is only one out of a group of solutions. The strategy pattern is actually one of the more common solutions to avoiding O/C violations, as it's better to prefer composition over inheritance - you don't extend the class to add functionality, rather expose new strategies to the clients.

    Bottom line is this isn't how enums should be used, I think we all agree on that.
    Reply With Quote  
     

  13. Thankful user:


Page 5 of 7 FirstFirst ... 34567 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Replies: 6
    Last Post: 08-12-2011, 03:41 AM
  2. Replies: 1
    Last Post: 01-15-2011, 01:05 AM
  3. Replies: 12
    Last Post: 10-31-2010, 10:22 PM
  4. Replies: 1
    Last Post: 04-27-2010, 01:34 AM
  5. Replies: 10
    Last Post: 05-31-2009, 01:42 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •