What Good Is an Empty Interface?

แชร์
ฝัง
  • เผยแพร่เมื่อ 9 ก.ค. 2024
  • An empty interface can be a powerful tool in the hands of a knowledgeable programmer. Therefore, stop asking whether an empty interface is a good tool - because it is. Instead, ask yourself if you understood it well enough to use it where it can shine.
    Download source code ► / zoranhorvat
    Join Discord server with topics on C# ► codinghelmet.com/go/discord
    Enroll course Beginning Object-Oriented Programming with C# ► codinghelmet.com/go/beginning...
    Subscribe ► / @zoran-horvat
    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
    👨 About Me 👨
    Hi, I'm Zoran, I have more than 20 years of experience as a software developer, architect, team lead, and more. I have been programming in C# since its inception in the early 2000s. Since 2017 I have started publishing professional video courses at Pluralsight and Udemy and by this point, there are over 100 hours of the highest-quality videos you can watch on those platforms. On my TH-cam channel, you can find shorter video forms focused on clarifying practical issues in coding, design, and architecture of .NET applications.❤️
    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
    ⚡️COPYRIGHT NOTICE:
    The Copyright Laws of the United States recognize a "fair use" of copyrighted content. Section 107 of the U.S. Copyright Act states: "Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phono records or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright." This video and our TH-cam channel, in general, may contain certain copyrighted works that were not specifically authorized to be used by the copyright holder(s), but which we believe in good faith are protected by federal law and the Fair use doctrine for one or more of the reasons noted above.
  • วิทยาศาสตร์และเทคโนโลยี

ความคิดเห็น • 119

  • @swekster
    @swekster 19 วันที่ผ่านมา +43

    As Confucius said, a bowl is most useful when it's empty :)

  • @martinpolansky9154
    @martinpolansky9154 19 วันที่ผ่านมา +12

    In general I find interfaces good. They can solve many issues. However I personally following the rule: "abstraction should be discovered not defined". What I mean by that is that e.g. in your example it would take me couple of tries and fails to discover the IEdition. If you are more lucky you can define it maybe up front. Great video btw. as always. 👍 Thanks

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา +11

      Actually, if you take the previous video in which I developed this object model, you will see that the interface came up quite late during development to substitute a plain int.
      It popped up as a solution to the inability to represent certain states and it was, somewhat ironically, empty on the outset. That made a few commenters incorrectly call it a marker interface, which it never was. Hence this video.
      But I generally agree with your comment. Abstractions come later.

    • @juliansegura5507
      @juliansegura5507 18 วันที่ผ่านมา +3

      Love this concept. Gotta discuss it with my devs.

    • @Veretax
      @Veretax 18 วันที่ผ่านมา

      I feel like rigorous application of that idea you may have some initial models of entities that you know you're going to have so you're going to create those at the start I think where the principal is useful is considering whether adding another interface which represents another Behavior in some Frameworks you have hundreds of interfaces on classes and it is so messy

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 18 วันที่ผ่านมา +1

      I agree that abstraction should arise organically, but humans are blessed with the ability to identify and apply patterns. Once you learn this idea you will notice that it solves certain problems. Then you can apply it directly in the future. For example, I don't need to toggle programs in on the front panel of an Altair to appreciate and apply the abstraction of 4th generation languages like C#.

  • @williamliu8985
    @williamliu8985 19 วันที่ผ่านมา +15

    Dear Zoran, you are one of the few youtube uploaders that I have to slow down the video speed to keep up with. 😂

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา +7

      Is that because of the speech or because of the code? I am fighting the opposite issue - when I leave pauses in the recording, people massively leave during the video....

    • @williamliu8985
      @williamliu8985 19 วันที่ผ่านมา

      @@zoran-horvat Haha, I like the feeling of knowledge flooding into my brain...

    • @MM-zm7ck
      @MM-zm7ck 18 วันที่ผ่านมา +5

      @@zoran-horvat for me, it's because of the concepts of your video are too advance. took me sometimes to understand. however I like your video even I don't really understand it .

    • @nickbarton3191
      @nickbarton3191 18 วันที่ผ่านมา +3

      @@zoran-horvat From my POV, two things. Leave the code to show for 20 seconds longer so I can read it and appreciate it before moving on.
      Secondly, speak in that ever so calm voice of yours, which is so reassuring, so we believe that we too can create such art. One or two videos your voice got a bit strident.
      In a short, I reckon you should've said only one thing, here you said two. I remembered only the second reason for empty Interface(s).

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 18 วันที่ผ่านมา +6

      ​@@zoran-horvat in my opinion your speech is clear and concise. The information is well considered and presented. But it's advanced so it takes time to absorb it. I think you don't need pauses in the video, as people will pause/rewind as needed. I often watch your videos multiple times and leave video in middle to transfer devices, or once I fully comprehend the ideas you've shared.

  • @djupstaten2328
    @djupstaten2328 19 วันที่ผ่านมา +5

    It can be a handy constraint object.

  • @ddanielsandberg
    @ddanielsandberg 19 วันที่ผ่านมา +2

    Feel like this pattern is common on JVM/CLR because we don't have a separate form for structured algebraic types. They both seem to merge typical OOP inheritance and types into interfaces/inheritance to emulate structured types. But I just woke up and may be wrong. :)

  • @billy65bob
    @billy65bob 19 วันที่ผ่านมา +4

    I quite like these for enforcing type constraints, I very rarely use them though.
    The only alternative I could think of was to use object as the type, and that is a giant can of worms.
    Personally I far prefer the safety and guarantees of an empty interface.
    EDIT: Pretty much your 'SuperType"

  • @PurpleDaemon_
    @PurpleDaemon_ 11 วันที่ผ่านมา

    It also can be a part of optimization related to the generics Code Explosion. When you just specify T, compiler has to generate native code for every value type, but if you specify an empty interface as a "where T: ..." condition, it will have to do this only for a limited set of types.
    This is used heavily in game dev.

    • @zoran-horvat
      @zoran-horvat  11 วันที่ผ่านมา

      @@PurpleDaemon_ Actually, compiler only generates generic types for distinct sizes of types. All value types with the same size share one compiled type. That is one of the nice details from the early days of .NET.

    • @PurpleDaemon_
      @PurpleDaemon_ 11 วันที่ผ่านมา

      @@zoran-horvat yes, you are right. But in big ECS projects it is common to have hundreds if not thousands of different structs, so it still makes sense.

  • @AdonikamVirgo
    @AdonikamVirgo 13 วันที่ผ่านมา

    Since classes implicitly inherit from Object, every marker interface still permits type-switching (preferably sealed internal) but will also allow modelling multiple related models that only need ToString, GetHashCode and/or Equals

  • @666nevermore
    @666nevermore 18 วันที่ผ่านมา

    I have a question Zoran.
    In your second example why wasn’t that an abstract class Edition?
    Since your other classes are MonthlyEdition or SeasonEdition it looks sound to me for them to inherit from an abstract class that collects them. What would change? Of course I could be totally wrong but this is what my mind would have done on the first take

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +2

      Subclassing is the inheritance relationship and interface implementation is the subtyping relationship. The latter asks for less obligations. Therefore, when there is nothing to inherit, I pick the interface.

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 18 วันที่ผ่านมา

      Abstraction implies shared behavior. Literally shared code through protected members. Interface is purely structural contract. Interface guarantees presence of members, but not implementation. Since a class can implement multiple interfaces its more flexible. Like a human that can be a father, son, brother, husband. These are interfaces. Human is the ancestor class.

  • @nickbarton3191
    @nickbarton3191 18 วันที่ผ่านมา +2

    Glad you favour evolution over OCP, how we tie ourselves in knots because of it. We can't know everything at the beginning, it's the same reason agile is better than waterfall.
    I'm constantly readjusting code when I see a better encapsulation.
    Great video, going to watch the longer version.

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 18 วันที่ผ่านมา

      Constantly adjusting code is a great point. I encounter junior devs who think once it builds and tests pass they're finished. Then they ask me why my code is so resilient and better organized. So I share Zoran vids and tell them to rewrite their code on a regular basis.

    • @nickbarton3191
      @nickbarton3191 18 วันที่ผ่านมา +2

      @@7th_CAV_Trooper Before nearly every new feature, I refactor to make the implementation of it easier. Just adding features leads to a ball of mud. All backed by thorough unit and integration automated tests.

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 18 วันที่ผ่านมา +1

      @@nickbarton3191 I love it. Have you checked out Kent Beck's "Tidy First" book?

    • @evancombs5159
      @evancombs5159 18 วันที่ผ่านมา +1

      Agile is waterfall

    • @nickbarton3191
      @nickbarton3191 18 วันที่ผ่านมา +1

      @@evancombs5159 I spelt it all lower case agile, which means iterative development. Decidedly NOT agile. Agile has been hijacked by companies selling a processes which aren't agile.

  • @alfonsdeda8912
    @alfonsdeda8912 18 วันที่ผ่านมา

    Hi Zoran, great video!
    Another way to use an interface couldn't be to use for returning a generic interface to a not generic class?

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +1

      It is frequently the case that a non-generic class implements a generic interface by fixing its generic type arguments. It is very useful in practice. For example, any generic extension methods then apply to the concrete class.

  • @CharlesBurnsPrime
    @CharlesBurnsPrime 17 วันที่ผ่านมา

    I use empty interfaces for type checking, such as checking whether a table poco is a link table vs. an table, and for grouping attributes.

    • @milasudril
      @milasudril 2 วันที่ผ่านมา

      You get no type safety from an empty interface. If I were to use the pointer, I have to downcast to whatever the type is expected to be.

  • @user-oy2bp9bq5m
    @user-oy2bp9bq5m 18 วันที่ผ่านมา

    4:48 Talking about strongly typed languages, it would be also interesting to hear your opinion on IoC containers, that makes the DI management hell

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +2

      I don't think DI is hell. It is only used in one place, at the composition root. Your custom code cannot observe its existence.

  • @Kitulous
    @Kitulous 17 วันที่ผ่านมา

    I wonder how EF works with empty interfaces like in the IEdition example...

  • @makp0
    @makp0 19 วันที่ผ่านมา

    What if editions are not sequential? Thus, requiring to pass args specific to each edition implementation.

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา

      There could be an overload to support that request.

  • @DanimoDev
    @DanimoDev 19 วันที่ผ่านมา

    I think as long as their purpose is by design and they are not mis/overused, then it's fine, which is my general rule for all anti-patterns imo, some anti-patterns are really useful in the right conditions.

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา +4

      You are using the term antipattern as a general determinant, but there is no antipattern as a thing in programming. An antipattern occurs when a concept is used in the wrong or harming way. Therefore, anything you take can be an antipattern, or not, depending on its use.
      To cut the long story short, saying that a marker interface is an antipattern is logically incorrect, since it also has its legitimate use where it is a pattern.

    • @DanimoDev
      @DanimoDev 19 วันที่ผ่านมา +1

      Agreed, and the point I was making is that many programmers, particularly when learning patterns, will see a pattern coined as an "anti-pattern" and vigorously avoid them. I avoided singletons like the plague for some time for this very reason as I assumed that anti-patterns == never use. I think this can be harmful as there are places for these kinds of patterns and they should be understood and used appropriately, but not to be entirely removed from your toolset or design considerations.

  • @justinerdmier
    @justinerdmier 14 วันที่ผ่านมา

    This is how I know I am still very much a junior dev. I absolutely love and agree with the concepts you're teaching, but I have never found any resources that teach this level of in-code design that also translates well to data hydration. If everything was in-memory, this would be perfect, but realistically, this data is being saved to a relational database. How do I use an interface such as IEdition as a type and store that to the db and easily retrieve it (ideally with EF Core)?

    • @zoran-horvat
      @zoran-horvat  14 วันที่ผ่านมา +1

      @@justinerdmier I plan to address that theme in a separate video later.

    • @justinerdmier
      @justinerdmier 13 วันที่ผ่านมา +1

      @@zoran-horvat That would be amazing!!! I am dedicated to learning DDD and being a strong advocate for it, and always do my best to implement it with personal project. However, it's difficult to really sell my team on it at work when I can't readily/easily apply it to the more complex design issues we have (which defeats the purpose of using it).
      Your content has been so helpful! I plan to subscribe to your Patreon when I get paid next.

  • @okcharles7
    @okcharles7 18 วันที่ผ่านมา

    Someone says that markers (interfaces or something else) should be replaced with attributes as C# has evolved that way.
    However, I can't find a way to get help from the attribute marker during compile time.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +1

      There were quite a few comments on this video quoting that "favor attributes over marker interfaces", but none of the commenters saw that the attribute cannot be applied to the example from this video. Some people are so short-sighted and yet feel no trouble to share their opinion.
      The attribute is a better option if you are already doing the analysis by reflection. Attribute does not apply if you are doing the assignment. That is all there is.

    • @zoran-horvat
      @zoran-horvat  17 วันที่ผ่านมา

      @@fusedqyou To cut the long story short, there is no solution that is based on attributes and both compiles and works on the example from the video. It is your homework to figure out why.
      From what I see, you don't have the faintest idea about what you said, and you were so arrogant to keep "correcting" me all day long without seeing the issue in your design.
      By the way I never said marker interface does nothing "yet". Marker interface does nothing. Full stop. It constrains the generic type. You have mixed up the demos.

    • @zoran-horvat
      @zoran-horvat  17 วันที่ผ่านมา

      @@fusedqyou You forgot to show the code.
      Ah yes, your code is not possible to write.

    • @zoran-horvat
      @zoran-horvat  17 วันที่ผ่านมา

      @@fusedqyou I have considered the alternative and it does not work. You don't have two lines of code to show your idea, but you still whine around. Sit down and write your code. Then we can talk. Of course, it must work. Be careful.

    • @fusedqyou
      @fusedqyou 17 วันที่ผ่านมา

      @@zoran-horvat 👎

  • @eugene5096
    @eugene5096 19 วันที่ผ่านมา

    Does empty record feels more fit in this case ? And of course usage of records for childs

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา

      A record is a class and a class defines the inheritance relationship. So long as there is nothing to inherit, I stay with the interface.

  • @charlotonne8980
    @charlotonne8980 18 วันที่ผ่านมา

    I recall reading some opinions where a marker interface ought to be replaced with Attributes, but I agree with you that the marker interface enables some useful features, and Attributes don't have those same features. Thanks, as always, for your helpful explanations of your own design choices. I always learn at least a little something when I tune in.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +1

      If you run an analysis, such as reflection or a fitness function, then the marker interface and the attribute are equally powerful, with the interface ending up being worse because it becomes the part of the type system to which it does not belong. If, however, you use it in assignments and constraints, like in my demo, then the attribute does not apply. It either won't compile (the second example), or it won't make the desired effect (the first example).

    • @charlotonne8980
      @charlotonne8980 18 วันที่ผ่านมา

      @@zoran-horvat Absolutely; I appreciate the succinct explanation between the differences. In recent projects, I've found markers useful for gating REST API responses on generic client implementations, but I could see attributes and reflection being useful if one used a less flexible base for it.

  • @sabbib007madness
    @sabbib007madness 17 วันที่ผ่านมา

    in JVM, the question arises, why not use an annotation as it's an empty interface? does c# have annotation, if it does, then why not use that instead?

    • @zoran-horvat
      @zoran-horvat  17 วันที่ผ่านมา

      There are annotations in C#, but they have no effect at compile time, nor can they be used to constrain assignments. Therefore, we only substitute a marker interface with an attribute if it was not a compile-time check the reason why we added them. In both examples in this video, it was the type check I needed, and only the proper type can do what I needed in C#.

    • @Kitulous
      @Kitulous 17 วันที่ผ่านมา

      aren't Java annotations analogous to C# attributes? that is, they just mark the object for the Reflection to grab the info? I thought you only could access annotations through the reflection not through the regular language syntax

    • @sabbib007madness
      @sabbib007madness 17 วันที่ผ่านมา

      @@Kitulous in JVM, annotations can be quite powerful.
      they can act as a "meta-type" on traditional types (including primitives) at compile time. so a function param can be annotated with and only types with those annotation can be accepted.
      it can be used at reflection
      it can be used to generate code prior to compiling

  • @nicknick8884
    @nicknick8884 14 วันที่ผ่านมา +1

    Дякую!

  • @adrianspikes6454
    @adrianspikes6454 17 วันที่ผ่านมา +1

    Thanks I only had to rewind once to understand...I'm slow 🤷

  • @gligom
    @gligom 19 วันที่ผ่านมา

    “If your design includes empty interfaces that types are expected to implement, you are probably using an interface as a marker or a way to identify a group of types. If this identification will occur at run time, the correct way to accomplish this is to use a custom attribute. Use the presence or absence of the attribute, or the properties of the attribute, to identify the target types. If the identification must occur at compile time, then it is acceptable to use an empty interface.”
    From Microsoft

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา

      @@fusedqyou You forgot to give the working code along with that opinion. I was so kind to ask for your code, but there seems to be none that works.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา

      The use of attributes requires additional infrastructure, which may be justified in large projects and frameworks, specifically accompanied with source generators and/or fitness functions. When applied to generics, as in my demo, the marker interface is a perfect compile-time companion that addresses the problem. In my opinion, a marker interface does not address the problem correctly if there is no assignment or a generic constraint. Both are compile-time, if you note.

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 18 วันที่ผ่านมา

      @@fusedqyou attributes provide no guarantee to compile time correctness and require RTTI. Further, I can't add a property that only accepts instances of a certain attribute. Why would you want to write code to enforce rules that the compile will enforce for you.

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 17 วันที่ผ่านมา

      @@fusedqyou because it's a type.

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 17 วันที่ผ่านมา

      @@fusedqyou show me how to prevent passing a class with a marker attribute to a method at compile time.

  • @lettuceturnipthebeets790
    @lettuceturnipthebeets790 19 วันที่ผ่านมา

    still, marker interfaces are awesome! specifically for reflection and generics

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา

      They have their role in generics, yes.

  • @evancombs5159
    @evancombs5159 18 วันที่ผ่านมา +1

    I would call it a placeholder interface. It represents a concept that exists, but is not well defined.
    In this specific case, I would give IEdition two properties string Name and int Version. These are the two attributes that define all editions no matter if it is a monthly edition, yearly edition, or just some randomly timed edition. This also means you are able to keep track of the order the editions came out while not relying on the editions name for that ordering.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +1

      That sounds like a good name for this concept.

  • @asagiai4965
    @asagiai4965 19 วันที่ผ่านมา +2

    Wait some people just learning the benefits of empty interface?

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา +1

      Actually, some people advocate against using them, hence this video to explain the benefits and use cases.

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา +1

      @@fusedqyou Saying that it is not the use of an interface to be a supertype goes against the very definition of an interface, which is a supertype. In addition to that, my guess is that you do not have a working solution based on attributes for either of the two use cases shown in the video.

    • @zoran-horvat
      @zoran-horvat  19 วันที่ผ่านมา

      @@fusedqyou Fine. Give me the working code without interfaces in my example.

    • @asagiai4965
      @asagiai4965 19 วันที่ผ่านมา +1

      @fusedqyou you said that, but in reality, technically, the only purpose of an interface is being a binding contract.
      And a contract doesn't need to have anything inside.

    • @fusedqyou
      @fusedqyou 19 วันที่ผ่านมา

      @@asagiai4965 An interface in C# is a contract that defines a set of methods, properties, events, and indexers that a class or struct must implement. It's not just merely a contract.

  • @jayleejw1801
    @jayleejw1801 15 วันที่ผ่านมา

    Enough with programming paradigms or something. Doesn’t matter at all.

  • @jayleejw1801
    @jayleejw1801 15 วันที่ผ่านมา

    Empty interface says nothing, as Gopher says :)

  • @adambickford8720
    @adambickford8720 18 วันที่ผ่านมา

    In java it's definitely an anti-pattern. Marker interfaces are poor man's metadata, which is almost certainly handled better via annotation (attributes).
    I also strongly disagree with this whole approach to design. It's easier to add code than to change it, so wait until you have provable value by adding it. This is approach adds accidental complexity; now we have to maintain a vestigial interface, praying it actually predicted the future correctly. If we're lucky it works, if not we either shoehorn it in or re-write the abstraction anyway. Or... we could wait until we *know* what an 'edition' is and model with the simplest, not most flexible, abstraction.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +1

      This interface has predicted the past, not the future. It has superseded an int edition field, which was insufficient to represent the requested versatile states as the design progressed.
      I have already made that reference in the video, and placed the link to the video that shows that process.

  • @Akronymus_
    @Akronymus_ 18 วันที่ผ่านมา

    IMO it ought to not even be an interface, but rather a discriminated union to denote the different possibilities. But as C#, unlike F#, doesn't support DU's yet, this seems like the next best solution.
    But tbh, that's probably down to me preferring a more functional approach over an OOP one.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +1

      A discriminated union is not the best choice when the list of subtypes is open-ended and/or not known at the time of writing.

    • @Akronymus_
      @Akronymus_ 18 วันที่ผ่านมา +1

      @@zoran-horvat Fair point, I forgot about extension of subtypes making sense in this case, as editions can be pretty much arbitrary, but all have the same functionality.

  • @aethernova
    @aethernova 18 วันที่ผ่านมา

    - How to protect anti-patterns?
    - Make video where you say, no, its not anti-pattern, for each of it.
    - Well, how about GO TO...
    - Forget, its totally broken.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +3

      This doesn't qualify as funny. It's more of a sour grape kind of whining.

    • @aethernova
      @aethernova 18 วันที่ผ่านมา

      Peoples can use any "anti-patterns" for youself, but many of it is really wrong things and dont need to say - no, its ok. Fire is fire. Who can use fire - use it. But is still fire, not water.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา

      @@aethernova There is no such thing as "X is an antipattern" for any X.

  • @AlgoristHQ
    @AlgoristHQ 17 วันที่ผ่านมา

    This makes DDD less valuable. Repositories should be able to return any logical set of data instead of just aggregate entities. DDD is a computer scientist trying to force invalid ideas onto software engineers.
    Take what works and leave the rest of DDD in the gutter...
    Edit: stop with the inheritence garbage in repositories. It only serves to confuse every developer on the team. This isn't readable and therefore it isn't maintainable.

    • @zoran-horvat
      @zoran-horvat  17 วันที่ผ่านมา

      Where did you see inheritance in repositories?

    • @AlgoristHQ
      @AlgoristHQ 17 วันที่ผ่านมา

      Correct, it isn't inheritance. I typoed when I meant interface implementation. The point still stands. This is a physicist building a bridge. Can they do it? Sure! Should they? No... They don't know the best practices of a civil engineer...

  • @umdi3337
    @umdi3337 18 วันที่ผ่านมา +1

    Empty interfaces are usually an anti-pattern and a code smell for poor object modeling. In your case there is an empty IEdition interface incorporated in the Book entity because you sequesed periodicals (magazines, news bulletins etc) and normal books into the same Book entity. Both publications have an edition property but with different meaning. Right thing to do would be creating an abstract base class named "Publication" and derive "Periodical" and "Book" from it. In this case their editions would be dedicated, non-empty classes (or interfaces). There are other reasons for this too, such as periodicals don't have authors but books do.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +2

      A single distinction does not warrant the invention of a hierarchy. How would you go around when other punctual distinctions appear? Would you introduce 2^n classes to model n concepts?
      My design is following the principle that polymorphism fits components better than the classes, i.e. it favors composition over inheritance.

    • @umdi3337
      @umdi3337 18 วันที่ผ่านมา

      @@zoran-horvat There are multiple and fundamental distinctions between periodicals and books, like the authors I mention in my previous answer, which obviously warrants separate classes and I never said create new derived classes for every distinction. Composition is not fitting everything in a single class, doing so is called a blob, which is the mother of all anti-patterns.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา +2

      @@umdi3337 Actually, you did say create a new subhierarchy whenever a new distinction appears. Only you didn't notice that you said it. There is a long discussion about the fallacy advocated in your comments, the comments section being too narrow to contain in its full size.

    • @umdi3337
      @umdi3337 18 วันที่ผ่านมา

      @@zoran-horvat In which sentence I said this? Can you copy and paste it here? As you can see my comments are not edited.

    • @zoran-horvat
      @zoran-horvat  18 วันที่ผ่านมา

      @@umdi3337 There is no behavior that is specific for one subtype or the other, and yet you said the problem "warrants" two distinct classes that share an abstract superclass. Apply that n times in a row and you'll end up with 2^n classes in the best tradition of the 1990s that almost got OOP killed.

  • @9739718777
    @9739718777 12 วันที่ผ่านมา +1

    No nonsense, Truly enjoyable, valuable high quality content ❤