OOP Concepts

by andrei 16. August 2008 14:53

You can read about the purpose of this list and how to use it here.
Also, the list of resources is here.

 

  1. general implementation
    E1
    E2
  2. concepts
    1. AOP
      What AOP promises to do for you is to allow you to separate crosscutting code, such as logging or security, into aspects and to apply those aspects easily to all the classes and methods that need them.
      It also allows you to separate business rules from the core logic and to change your existing objects by adding both state and behavior to them.
      itwith only three lines of code you have applied the logging advice to all the methods of the Calculator instance and obtained a reference to it. You can now call any method on it, and you will see that the calls are properly logged.
      resources
      B4
      E15
      1. Moving Business Rules into Aspects
        The best candidates are rules that cause secondary logic to be implemented along with the core logic.
        While you could argue that the minimum balance check should remain in the Account class, it is obvious that the notification sending code is not the primary functionality of the Withdraw() method
        resources
        B4
      2. object locking
        combination of introduction and before advice to implement and enforce object locking
        resources
        B4
      3. Adding State and Behavior
        leverage AOP features and declaratively add locking support only to the classes that need it. This can be easily accomplished using a combination of introduction and before advice.
        resources
        B4
      4. logging
        we can leverage AOP to solve the problems associated with the previous logging code
        resources
        B4
      5. spring .net
        www.springframework.net
      6. aspect
        An aspect groups advices and the pointcuts they apply to, which is in a way similar to how a class groups data and associated behavior together.
        resources
        B4
      7. pointcut
        A pointcut identifies a set of joinpoints where advice should be applied. For example, if you want to apply transaction advice to all the methods that are marked with transaction attribute, you would have to declare a pointcut that identifies those methods.
        resources
        B4
      8. joinpoint
        A joinpoint is any place in the code where an advice could be applied. In theory, a joinpoint could be almost anythinginstance variable, for loop, if statement, and so on. In practice, however, most commonly used join-points are classes, methods, and properties.
        resources
        B4
      9. introduction
        An introduction is a somewhat special type of advice that only applies to classes. Introductions allow you to introduce new members into existing classes, both state and behavior, and could be used to achieve the benefits of multiple inheritance in languages that do not support it, without its tradeoffs. (Introduction is called mixin in some languages.)
        resources
        B4
      10. advice
        An advice is a piece of code that you want to encapsulate and reuse. For example, logging code would be implemented as an advice and applied wherever you need it. There are several types of advice, such as before, after, and around advice.
        resources
        B4
    2. Fluent Interface
      resources
      B4
    3. visitor
      code & implementation
      E2
      1. visitor framework
        code & implementation
        E2
    4. Template Method pattern
      you define the overall algorithm, or template method, in a base class
      the subclasses can inherit from TotalBase and provide a custom implementation of the VariationPoint() method
      resources
      B3
      B4
      code & implementation
      B3
    5. state pattern
      The idea is to encapsulate the different states as individual classes (see ConcreteStateA and ConcreteStateB). Those concrete state classes inherit from an abstract State class. Context has a state instance as a field and calls Handle() of the state instance when Context gets a Request() call. Handle() has different implementations for the different state classes.
      As we specified, orders have an acceptance status. Therefore, I just add a method called Accept(). I leave the decision about whether or not to internally use the State pattern for later. It is better to make implementation decisions like this during refactoring.
      resources
      B4
      code & implementation
      B4
    6. standalone class
      A STANDALONE CLASS is an extreme of low coupling.
      In an important subset, the number of dependencies can be reduced to zero, resulting in a class that can be fully understood all by itself, along with a few primitives and basic library concepts.
      Low coupling is fundamental to object design. When you can, go all the way. Eliminate all other concepts from the picture. Then the class will be completely self-contained and can be studied and understood alone.
      Try to factor the most intricate computations into STANDALONE CLASSES, perhaps by modeling VALUE OBJECTS held by the more connected classes.
      resources
      B1
    7. singleton
      More and more often the Singleton pattern is considered a worst practice. The reason for that is you create global instances, which are often a problem in themselves. Another problem is that singletons often make the tests harder to write (remember, testability is crucial), and the interaction with the singletons isn't very clear in the code.
      Dependency Injection will gracefully reduce the problem of too many singletons
      resources
      B4
    8. Single Responsibility Principle (SRP)
      An item such as a class should just have one responsibility and solve that responsibility well. If a class is responsible both for presentation and data access, that's a good example of a class breaking SRP.
      B4
    9. Separated Interface Pattern
      Again, just like with the Repository interfaces and the RepositoryFactory , by using the combination
      of interface and Factory, it allows me to implement the Separated Interface Pattern (Fowler). In other
      words, I can keep the interface separate from the implementation and yet still create instances of the
      interface and use those instances without even knowing what they are.
      resources
      B3
      code & implementation
      B3
    10. responsibility-driven design
    11. public field vs property
      I used to hate them myself, but I have since changed my mind. As long as the fields are both readable and writable and no interception is needed when reading or writing the values, the public fields are at least as good as properties. The good thing is that they are simpler; the bad thing is if you need to intercept when one of the values is set.
      public properties can't be used as ref arguments, but that's possible with public fields.
      resources
      B4
    12. patterns
      A design pattern should be applied only when it is needed.
      the way to most often use patterns isn't to use them in up-front design, but to refactor toward or to patterns
      resources
      B1
      B4
      1. list of patterns
        resources
        E18
    13. operations
      Operations can be broadly divided into two categories, commands and queries
      resources
      B1
      1. value object
        apart from initializers called only during creation, all their operations are functions
        value objects are safer to use and easier to test
        After completing the refactoring to separate modification from querying, consider a second refactoring to move the responsibility for the complex calculations into a VALUE OBJECT. The side effect often can be completely eliminated by deriving a VALUE OBJECT instead of changing existing state, or by moving the entire responsibility into a VALUE OBJECT.
        contain either just data or just behavior. The ones that contain only data are also known as Data Transfer Objects (DTOs)
        When we go for a Value Object pattern, it might feel obvious that we should use a struct in .NET instead of a class, but there are recommendations for size regarding when to use a struct and when not to, and you'll get more problems with infrastructure when it comes to structs. It's also the case that you will see more boxing when using structs, so the decision isn't clear-cut. I'm actually leaning to using classes, but most often I'm making them immutable. If you go that route, you need to use all the values of the class for when you are overriding the Equals().
        resources
        B1
        B3
        B4
      2. side-effect free function
        Complex logic can be done safely in SIDE-EFFECT-FREE FUNCTIONS
        resources
        B1
      3. side effect
        any effect on the state of the system. Elements of a complex design interact in other ways that are likely to produce unpredictability. The use of the term side effect underlines the inevitability of that interaction.
        resources
        B1
      4. separation
        An operation that mixes logic or calculations with state change should be refactored into two separate operations
        resources
        B1
      5. query
        Queries obtain information from the system, possibly by simply accessing data in a variable, possibly performing a calculation based on that data.
        resources
        B1
      6. predictability
        Interactions of multiple rules or compositions of calculations become extremely difficult to predict. The developer calling an operation must understand its implementation and the implementation of all its delegations in order to anticipate the result. The usefulness of any abstraction of interfaces is limited if the developers are forced to pierce the veil. Without safely predictable abstractions, the developers must limit the combinatory explosion, placing a low ceiling on the richness of behavior that is feasible to build.
        you can keep the commands and queries strictly segregated in different operations. Ensure that the methods that cause changes do not return domain data and are kept as simple as possible. Perform all queries and calculations in methods that cause no observable side effects
        Second, there are often alternative models and designs that do not call for an existing object to be modified at all. Instead, a new VALUE OBJECT, representing the result of the computation, is created and returned
        Place as much of the logic of the program as possible into functions, operations that return results with no observable side effects. Strictly segregate commands (methods that result in modifications to observable state) into very simple operations that do not return domain information. Further control side effects by moving complex logic into VALUE OBJECTS when a concept fitting the responsibility presents itself.
        resources
        B1
      7. function
        Operations that return results without producing side effects are called functions. A function can be called multiple times and return the same value each time. A function can call on other functions without worrying about the depth of nesting. Functions are much easier to test than operations that have side effects. For these reasons, functions lower risk.
        resources
        B1
      8. command
        Commands (also known as modifiers) are operations that affect some change to the systems (for a simple example, by setting a variable)
        resources
        B1
      9. automated unit tests
        If ASSERTIONS cannot be coded directly in your programming language, write automated unit tests for them. The test setup puts the preconditions in place; then, after execution, the test checks to see if the post-conditions hold.
        resources
        B1
    14. atomic operations
      resources
      B4
      1. overwriting values
        The problem is most likely to be that the operation isn't atomic. The value is first set (and therefore the old value is overwritten) and then checked (if remembered). Perhaps something like Customer.RequestCreditLimit(1000) would be a better solution.
        resources
        B4
    15. Open-Closed Principle (OCP)
      A class should be closed for modification, but open for extension. When you change a class, there is always a risk that you will break something. But if instead of modifying the class you extend it with a sub-class, that's a less risky change.
      OCP can easily be over-applied. You might have come to a point where you understand better how a method should be implemented and want to modify it rather than extend it. And adding a method to a class could also be seen as an extension.
      B4
    16. null object pattern
      Take an Order, for example. Assume that the shipment of an Order is taken care of by a transporter.
      At first, the Order hasn't been shipped (and in this case we have not thought much about shipment at all), so we can't give it any transporter object, but instead of just leaving the TRansporter property as null, I set the property to the empty ("not chosen," perhaps) transporter instead. In this way, I can always expect to find a description for the TRansporter property like this:
      anOrder.Transporter.Description
      If TRansporter had been null, I would have needed to check for that first.
      null objects increase the simplicity a lot and in unexpected ways as well.
      Something that is worth pointing out is that I expect the usage of Null Object in the previous code when I paint the orders. Because of that, all orders will have a ReferencePerson (an empty one), even if it hasn't been decided yet, so I don't need any null checks. In my opinion, this is an example of a detail that shows how to increase the simplicity for the UI programmer.
      resources
      B4
      code & implementation
      E2
    17. low coupling
      Low coupling is a basic way to reduce conceptual overload.
    18. Liskov Substitution Principle (LSP)
      Assume that you have an inheritance hierarchy with Person and Student. Wherever you can use Person, you should also be able to use a Student, because Student is a subclass of Person.
      resources
      B4
    19. interface
      Notice how the
      Transaction class only has to implement the IEntity interface and not inherit from the EntityBase
      class. This works out well because although a Transaction is an Entity, it does not need all of the
      functionality that the EntityBase class has, and therefore I can keep it lightweight.
      resources
      B3
      code & implementation
      B3
    20. intention-revealing interface
      All public elements of a design together make up its interface, and the name of each of those elements presents an opportunity to reveal the intention of the design. Type names, method names, and argument names all combine to form an INTENTION-REVEALING INTERFACE.
      Name classes and operations to describe their effect and purpose, without reference to the means by which they do what they promise. This relieves the client developer of the need to understand the internals. Write a test for a behavior before creating it, to force your thinking into client developer mode.
      resources
      B1
    21. factory method
      Factory Method is about deferring instantiation of the "right" class to subclasses.
    22. double dispatch
      This method is interesting to me because instead of just delegating to the protected abstract method
      PersistUser , it instead calls the RegisterChanged method of the IUnitOfWork instance
      When the IUnitOfWork
      instance ’ s Commit method is called, it calls back into the IUnitOfWorkRepository interface passed in
      with the RegisterChanged method
      resources
      B3
      code & implementation
      B3
    23. design by contract
      "assertions" about classes and methods that the developer guarantees will be true
      1. pre-conditions
        "Preconditions" are like the fine print on the contract, the conditions that must be satisfied in order for the post-condition guarantee to hold.
      2. post-conditions
        "post-conditions" describe the side effects of an operation, the guaranteed outcome of calling a method.
      3. invariants
        an invariant is a predicate that, if true, will remain true throughout a specific sequence of operations, is called (an) invariant to that sequence.
        resources
        A1
      4. class invariant
        a class invariant is an invariant used to constrain objects of a class. Methods of the class should preserve the invariant. The class invariant constrains the state stored in the object.
        Invariants can also be declared for entire AGGREGATES, rigorously defining integrity rules.
        resources
        A1
      5. assertion
        Methods that change system state can be characterized with ASSERTIONS. All assertions describe state, not procedures, so they are easier to analyze.
        Programmers often make use of assertions in their code to make invariants explicit. Class invariants make assertions about the state of an object at the end of any operation.
        resources
        B1
        A1
    24. constructor
      send all essential dependencies in the constructor
      it's good practice to not have much processing in constructors
      The reason that the RoutingItem class must pass a Discipline instance, a RoutingOrder value, a
      ProjectContact instance, and a DateTime value in its constructor is that the RoutingItem class needs
      to know who the item is being routed to ( ProjectContact recipient ), what that person ’ s discipline
      ( Discipline discipline ) is, and when ( DateTime dateSent ) it was sent to them. Without these
      values, the RoutingItem instance is useless.
      The Discipline , RoutingOrder , Recipient , and DateSent properties are all read - only, as their values
      can only be set in the constructor. In order to change these values, you must construct a new RoutingItem
      instance
      resources
      B3
      B4
      code & implementation
      B3
    25. composition over inheritance
      You may notice that in this diagram that a ProjectContact contains a Contact, but does not inherit from a Contact. This is purely my preference to stick with the Gang - of - Four advice by favoring composition over inheritance.
      resources
      B3
    26. command pattern
      code & implementation
      E2
    27. builder pattern
    28. associations
    29. abstract factory
      Abstract Factory is about creating families of dependent objects.
    30. closure of operation
      If we take two real numbers and multiply them together, we get another real number. Because this is always true, we say that the real numbers are "closed under the operation of multiplication": there is no way to escape the set. When you combine any two elements of the set, the result is also included in the set.
      A closed operation provides a high-level interface without introducing any dependency on other concepts.
      This pattern is most often applied to the operations of a VALUE OBJECT.
      An operation can be closed under an abstract type, in which case specific arguments can be of different concrete classes.
      you sometimes get halfway to this pattern. When the extra type is a primitive or basic library class, it frees the mind almost as much as CLOSURE.
      resources
      B1

 

You can find the entire list of techniques in progress in the Development base concepts category. Please feel free to leave any comments or suggestions which could make these lists more useful for everyone.

Also, if you are interested in learning these skills you can try the Developer training modules.

 

Technorati Tags: ,,

 

 

Enjoy programming!

 

I am putting together a set of concept lists for the main programming techniques, which should help developers learning or using them to be more efficient. Here are the techniques in progress:

Please feel free to leave any comments or suggestions which could make these lists more useful for everyone.

 

 

Also, if you are interested in learning these techniques you can try the developer training modules.

Again, please feel free to leave any comments or suggestions which could make the training modules more useful for everyone. We are having great results with them at Akcedo (so they really work), but they can always be improved. Also, if you would like to use the modules or are already using them and you want to discuss about the process feel free to comment and ask questions here.

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.4.5.0