Enterprise concepts

by andrei 17. August 2008 22:35

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
    B1
    B2
    B3
  2. concepts
    1. SOA
      an introduction to Service Oriented Architecture (SOA) that Udi Dahan has written
      resources
      B4
    2. partition
      Two possible partitions might be the subsystem for registering orders and the subsystem for administering user complaints. Both partitions might have a UI and a Domain Model.
      I think that first it's a matter of partitions, and then inside those partitions it's a question of layers, not the opposite
      resources
      B4
    3. indirection
      most problems in coding can be solved with another layer of indirection
      resources
      B4
    4. CRUD
      basic object life cycle states
      create, read, update, and delete
    5. persistence abstraction layer
      Thanks to that abstraction layer, I can move the Repositories back to the Domain Model, and I only need one Repository implementation per Aggregate root. The same Repository can work both against an O/R Mapper and against a Fake that won't persist to a database but only hold in memory hashtables of the instances, but with similar semantics as in the O/R Mapper-case.
      It's still a stretch to talk about PI Repositories, but with this solution I can avoid a reference to the infrastructure in the Domain Model. That said, in real-world applications I have kept the Repositories in a separate assembly anyway
      resources
      B3
      B4
      code & implementation
      E12
      1. delete
        the Delete() is quite interesting because it requires an Identity Map of its own for the Fake in the Unit of Work. Instances that have been registered for deletion will be held there until PersistAll(), when the deletion is done permanently.
        resources
        E12
      2. identity map
        The fake implementation uses two layers of Identity Maps
        The MakePersistent() is pretty simple; the instance is just associated with the first layer of Identity Maps. And when it's time for PersistAll(), all instances in the first layer are copied to the second layer. Simple and clean.
        resources
        B3
        B4
        code & implementation
        E12
    6. Snapshot pattern
      resources
      B4
    7. Identity Map pattern
      The idea with Identity Map is that you will not have two separate instances for a single customer. The Identity Map will take care of that for you.
      The language itself, C# for example, won't take care of this for you.
      resources
      B4
    8. Identity Field
      Saves a database ID field in an object to maintain identity between an in-memory object and a database row.
      Identity Field means a field that binds the row in the database to the instance in the Domain Model
      The simplistic solution I've adopted is to assume a property (or field) called Id. If the developer of the Domain Model has used another convention, it could be described to the Fake at instantiation of the FakeWorkspace.
      resources
      B4
    9. Web
      1. url creation, routing handling & validation
        code & implementation
        E2
      2. requestcontext from httpcontext
        code & implementation
        E2
      3. query string handling
        code & implementation
        E2
      4. namevaluecollection handling
        code & implementation
        E2
    10. UnitOfWork
      maintains a list of objects affected by a business transaction and coordinates the writing out of changes
      and the resolution of concurrency problems.
      I want to be able to do a lot of stuff to several different instances, and then persist all the work with a single call such as PersistAll().
      see the Unit of Work as something belonging to the consumer of the Domain Model (that is the Application layer or the presentation layer) rather than the Domain Model itself
      resources
      B3
      B4
      code & implementation
      B3
      B4
      E12
      1. Identity Map
        Unit of Work and Identity Map together over and over again. It's such a common combination, not only in my text, but in products as well. For example, there is Persistence Manager in JDO Jordan/Russell JDO and Session in Hibernate
        resources
        B4
      2. aggregate
        I expect it to be enough to associate the Aggregate root with the Unit of Work, the instances that are part of the Aggregate and that the Aggregate root reaches will get persisted to the database as well when we say PersistAll().
        Aggregates "should" be designed so that they are in a consistent state at PersistAll() time.
        resources
        B3
        B4
        code & implementation
        B3
      3. repository
        the Repository was fed with the _ws at instantiation time. In this way, I can control the Repositories that should participate in the same Unit of Work and those that should be isolated in another Unit of Work
        resources
        B3
        B4
        code & implementation
        B3
      4. keeping track
        I mentioned saving data previously. AddOrder() isn't really saving; it just adds the Order to the Repository. Or should it mean saving also? No, I don't think I want that behavior. What I want from AddOrder() is that the Repository (and the underlying infrastructure) from that point should know about the instance and deal with it when I ask for a PersistAll().
        the Add() call in notifying the Unit of Work that there is a new instance for persisting at next PersistAll() call
        resources
        B3
        B4
        code & implementation
        B3
      5. transactions
        Another thing that might be a problem is that when the Repository hid the Unit of Work it probably meant that there were two database transactions
        PersistAll() internally does all its work in an explicit transaction, even though you explicitly didn't ask for it
        I prefer to control the start and end of the unit of work in the consumer, outside of the repositories
        resources
        B3
        B4
        code & implementation
        B3
      6. synchronization
        a scenario should just have one Unit of Work and one Identity Map
        The reasoning for not letting the repositories completely hide the Unit of Work was that he
        wanted to synchronize changes across several Aggregates (and their respective repositories) in a single logical
        unit. In order for this to work, the repositories need to have a Unit of Work injected into them at creation time.
        I also chose to control save or not save (PersistAll()) outside of the Repositories. In this particular example, I could just as well have had PersistAll() directly on the CustomerRepository, but I chose not to. I often find that I want to synchronize changes to several Aggregates (and therefore also to several different Repositories) in a single logical unit, and that's the reason
        resources
        B3
        B4
        code & implementation
        B3
    11. UI strings handling
      code & implementation
      E2
    12. tracing
      As we just discussed, it's nice to be able to listen to what is going on at the same time as users run scenarios in the system. This is not only a very efficient solution for tracking down bugs, but it can be used for investigating where the bottlenecks are located, for example.
      If you have the possibility of using Aspect-Oriented Programming (AOP), it might not take more than a few minutes to add tracing afterward.
      resources
      B4
    13. System Metaphor
      When a concrete analogy to the system emerges that captures the imagination of team members and seems to lead thinking in a useful direction, adopt it as a large-scale structure. Organize the design around this metaphor and absorb it into the UBIQUITOUS LANGUAGE.
      resources
      B1
    14. string db queries handling
      code & implementation
      E1
      E2
    15. service locator
      means that a class internally locates its concrete collaborators through the dependency on another object (the locator). A simple example of a locator could be a factory object that uses a configuration file to load the required collaborators dynamically.
      resources
      B4
    16. Service Layer pattern
      scenario classes, delegating all the work to the Domain Model
      resources
      B4
    17. serialization
      As you might expect, the Serializer class contains two methods, Serialize and Deserialize .
      resources
      B3
      code & implementation
      B3
    18. Query Object
      The idea of the Query Object pattern is to encapsulate the criteria in a Query instance and then send that Query instance to another layer where it is translated into the required SQL.
      encapsulate queries as objects, providing object-oriented syntax for working with the queries
      we might use a Query Object, for example, inside the Repository
      resources
      B4
      1. complexity
        when the queries get complex, it's often more powerful to be able to write the queries in, for example, a string-based language similar to SQL
        resources
        B4
      2. In the Domain Model
        The consumer still gets the power of queries to be used for sending to Repositories, for example, but with a highly intuitive and typesafe API.
        //Consumer code
        CustomerQuery q = new CustomerQuery();
        q.Name.Eq("Volvo");
        resources
        B4
        1. specification
          similar to creating type safe Domain Model-specific queries, but it goes a step further because it's not generic querying that we are after, but very specific querying, based on domain-specific concepts
          resources
          B4
        2. aggregate
          Each of your Aggregates is a typical candidate for having Query Object in the Domain Model. Of course, you could also go the XP route of creating them when needed for the first time
          resources
          B4
      3. In Consumers of Repositories
        In the second case, the queries are set up in the consumers of the Repositories and sent to the Repositories as parameters. This is typically used in cases of highly flexible queries, such as when the user can choose to fill in any fields in a large filtering form. One such typical method on a Repository could be named GetCustomersByFilter(), and it takes an IQuery as parameter.
        resources
        B4
      4. In Repositories
        Probably the most common place to set up queries is in the Repositories. Then the queries become the tool for fulfilling method requests, such as GetCustomersByName() and GetUndeliveredOrders(). That is, the consumer might send parameters to the methods, but those are just ordinary types and not Query Objects.
        resources
        B4
      5. Querying and the Cache
        the GetByQuery() won't investigate the Identity Map before hitting persistence
        The reason is partly that we want to use the power of the backend, but above all that we don't know if we have all the necessary information in the Identity Map (or cache if you will) for fulfilling the query. To find out if we have that, we need to hit the database. This brings us to another problem. GetById() starts with the Identity Map; GetByQuery() does not. This is totally different behavior, and it actually means that GetByQuery() bypasses the cache, which is problematic. If you ask for the new Customer Volvo that has been added to the Identity Map/Unit of Work, but has not been persisted, it will be found if you ask by ID but not when you ask by name with a query.
        To tell you the truth, it was a painful decision, but I decided to let GetByQuery() do an implicit PersistAll() by default before going to the database.
        resources
        B4
    19. Pluggable Component Framework
      Distill an ABSTRACT CORE of interfaces and interactions and create a framework that allows diverse implementations of those interfaces to be freely substituted. Likewise, allow any application to use those components, so long as it operates strictly through the interfaces of the ABSTRACT CORE.
      resources
      B1
    20. performance monitoring
      Getting performance monitoring based on Domain Model information and other parts of your application is extremely helpful for tracking down problems, but also for keeping a proactive eye on the system. By doing that, you can easily track that it now takes perhaps 30% longer to execute a certain scenario compared to a time two months ago.
      B4
    21. MVP
      Even though the MVC pattern formally states that the Controller should receive the events and act upon the View, it is often more practical to have the View subscribe to the events and then delegate the handling onto the Controller.
      resources
      B4
      E16
    22. MVC
      The grandfather of patterns for connecting the UI to the application and domain layers is MODEL-VIEW-CONTROLLER
      The intent of the Model-View-Controller pattern (MVC) is to break UI behavior up into separate pieces in order to increase reuse possibilities and testability. The three pieces are the View, the Model, and the Controller.
      The key benefit of applying the MVC pattern is that it makes your UI code testable. Secondarily, it forces a very structured approach onto the coding/design process of the UI, which may in itself cause cleaner code in the end. You're forced to think a little more, so to speak.
      resources
      B4
      E16
      1. Combining Views/Controllers
        More complex Views are often made up of multiple smaller Views. Examples are wizards where the user navigates through a bunch of Views through next and previous buttons or maybe even jump back and forth several steps at a time. Information might be saved along the way, but it does not really get committed until the user clicks Save on the final screen.
        Another example is Master/Details Views where changes made to the details View might cause changes in the Master View as well.
        we could have a FlowController that controls the basic flow back and forth through the wizard, and each step could have its own View and Controller.
        In the Master/Detail, we might have the Controller for the Detail View raise an event on changes. Any other Controller could then subscribe to this event, including the Controller for the Master View.
        resources
        B4
        E16
      2. Decouple the Controller from the View
        the advantage of decoupling the Controller from the View is that we can vary the Controller behind the View. This can be very useful when a View can show up in a lot of different contexts, and it might not make sense to always have to enforce a particular Controller to go along with it.
        A simple solution is to create an interface for the Controller and have the View know about that only and not the actual implementation. A more complex way is to have Views raise events to anonymous subscribers (Observer pattern GoF Design Patterns). I'm not a big fan of this approach as I cannot imagine why one View would need to communicate user interactions to multiple subscriberslet alone subscribers of unknown types
        resources
        B4
        E16
      3. Adapters
        you might end up with very large interfaces if you have 10 input boxes and you need to be able to control the visibility, enabled, font, back color, fore color, border style, and so on of each of them.
        you can create an Adapter/Wrapper for each type of UI control you use. The Adapter for a TextBox could expose the mentioned properties, and the View interface would then only have to expose one property of the TextBoxAdapter data type for each textbox. Behind the scenes, the View would then provide references to the real UI controls to each Adapter during instantiation and the Adapter would simply delegate the call it receives to the actual implementation.
        resources
        B4
        E16
      4. controller
        Finally, the Controller, which is really the heart of the MVC, is the glue that ties the Model and the View together. The Controller receives messages when the user interacts with the View, translates those messages into actions that are performed on the underlying Model, and then updates the View accordingly.
        resources
        B4
        E16
      5. view
        The View should consist only of logic directly related to "painting the pixels on the screen." Keeping the View as "dumb as possible" is often the major design objective when applying MVC. The rationale is that Views/Screens in practice require a human eye to be tested. This is an error prone and costly process compared to automated unit tests.
        resources
        B4
        E16
    23. Model - View - ViewModel
      take a pure Model, create an abstract view that contained state, and data bind a View created with a visual designer to that abstract view.
      resources
      B3
      code & implementation
      B3
    24. messages (in layer and between layers)
      resources
      B3
      code & implementation
      B3
    25. logging
      Errors, warnings, and information messages must be logged. This is extremely important for investigating problems after they have occurred. We can't expect the users to write down the exact messages for us. It might also be that we want to collect information that we don't want to show to the users.
      resources
      B4
      code & implementation
      E2
      1. logging fwk
        code & implementation
        E2
      2. log4net
        http://logging.apache.org/log4net/index.html
        code & implementation
        E2
    26. Lazy Load
      The first solution that springs to mind is probably to add a TotalCredit property on the Customer. But this is problematic because it's then a bit too transparent, so that the consumer sees no cost at calling the property.
      Lazy Loading is an optimization technique and not something you have to use all the time
      resources
      B4
    27. large-scale structure
      Devise a pattern of rules or roles and relationships that will span the entire system and that allows some understanding of each part's place in the whole—even without detailed knowledge of the part's responsibility.
      Large-scale structure should be applied when a structure can be found that greatly clarifies the system without forcing unnatural constraints on model development.
      resources
      B1
    28. IoC & DI
      Dependency Injection, suggests that a class explicitly declares the interfaces of its collaborators (for example, in the constructor or as parameters in a method) but leaves the responsibility for the creation of their concrete implementation to the container. Because the class is not in control of the creation of its collaborators anymore, this principle is also known as Inversion of Control.
      makes the object that has the dependencies passive. The object declares its dependencies but is otherwise completely oblivious as to where the dependencies come from. The process for resolving the dependencies and finding the dependent objects is left to an external mechanism, which may be implemented in a variety of ways.
      IoC is not a pattern but a general principle that simply states that objects should rely on their environment to provide other objects rather than actively obtaining them
      we recognize the setter- and constructor-based approaches implemented by these containers as a concrete pattern and use the more specific name Dependency Injection for it
      distinguish between the Dependency Injection pattern and other types of IoC
      resources
      B4
      code & implementation
      E2
      1. Nested Containers
        When a container cannot satisfy all dependencies required to create a component, it tries to obtain the missing components from its parent container, which in turn can request components from its own parent container. This set-up broadly resembles the Chain of Responsibility design pattern
        In our application, a container is associated with the application. Additionally, each session has a child container, and for each request in a session, a child container of the corresponding session container is created.
        resources
        B4
      2. Castle Windsor
        resources
        B4
      3. Pico Container
        resources
        B4
      4. Spring .Net
        resources
        B4
      5. Contextualized Dependency Lookup
        A widely used pattern that adheres to the IoC principle but is not a Dependency Injection variant is Contextualized Dependency Lookup
        resources
        B4
      6. Setter Dependency Injection
        resources
        B4
      7. optional dependencies
        With constructor dependency injection, we express this by providing two constructors, one for each valid set of dependencies.
        It would also be possible to use a constructor with all arguments and pass in null for the optional ones, but this makes the contract less explicit, especially when the number of dependencies increases. It is therefore advisable to always provide one constructor for each valid set of dependencies and, if possible, to chain the constructors. If this seems impossible, it is probable that the class in question has too many dependencies and should be broken up.
        resources
        B4
      8. Constructor Dependency
      9. IoC & DI framework
        code & implementation
        E2
      10. Service Locator pattern
        The curve objects we are using in this example are data sources, but it is easy to see that we can use the same patterns to locate services providing objects (for example, an audit service that writes the calculated price to a log). Used in this way, the pattern is often referred to as Service Locator
        Using a Service Locator, we register a concrete curve implementation with the locator under a name, most likely the name of the interface. With this setup, our bond pricer can now get hold of the discount curve by asking the locator for one.
        resources
        B4
      11. Registry pattern
        In a further step toward complete decoupling, we can replace the factory with an implementation of the Registry pattern
        a registry provides objects of a given type but rather than hard-coding the type of object, it externalizes this decision and instantiates the objects using reflection
        The implementation of such a registry is simple but effective and finally achieves our goal of decoupling BondPricer from a concrete implementation of IDiscountCurve.
        resources
        B4
    29. instantiation based on configuration
      resources
      B3
      code & implementation
      B3
    30. Front Controller
      code & implementation
      E2
    31. evolving order
      Many developers have experienced the cost of an unstructured design. To avoid anarchy, projects impose architectures that constrain development in various ways. Some technical architectures do solve technical problems, such as networking or data persistence, but when architectures start venturing into the arena of the application and domain model, they can create problems of their own.
      resources
      B1
    32. efficiency
      The greatest value I've seen delivered has been when a narrowly scoped framework automates a particularly tedious and error-prone aspect of the design, such as persistence and object-relational mapping. The best of these unburden developers of drudge work while leaving them complete freedom to design.
      So you have to fight the temptation to build frameworks and regiment the implementation of the large-scale structure. The most important contribution of the large-scale structure is conceptual coherence, and giving insight into the domain. Each structural rule should make development easier.
      resources
      B1
    33. dto
      resources
      B3
      code & implementation
      E1
      E2
      1. data contract
        It is basically a Data Transfer Object (DTO) used to get data back and forth from the client to the server. All of the Data
        Contract classes are nothing but data, that is, they contain just a bunch of property setters and getters.
        Their main purpose in life is to be serialized and sent across the wire and then deserialized on the
        receiving end of the wire.
        resources
        B3
        code & implementation
        B3
      2. converter & mapper
        For every class in the domain model, there is an equivalent Data Contract class, and,
        for each set of classes, there is a ToEntity Name method and a ToEntity NameContract method.
        The ToEntity method assumes that the naming is consistent in the Converter class, and uses reflection
        to call the right method to convert a ContractBase instance to an IEntity instance.
        resources
        B3
        code & implementation
        E1
        E2
        1. mapper fwk
          code & implementation
          E2
    34. distribution
      First Law of Distributed Object Design, which is "Don't distribute" Fowler PoEAA. If you absolutely don't have to, don't do it
      resources
      B4
    35. db field names handling & mapping db tables
      code & implementation
      E1
      E2
    36. dates & times
      The next interesting bit of logic is the conversion of all of
      the DateTime argument values to Universal Time. Doing this allows the Client Membership system to
      standardize on one time zone for users who may be working around the country or the world.
      resources
      B3
      code & implementation
      B3
    37. database access
      resources
      B4
    38. configuration
      Have you had to recompile old applications just because the database server was switched to a new machine with a new name? I have. Of course, that kind of information should be configurable and depending on the application, this might be the case for loads of information.
      B4
      1. application configuration files handling
        code & implementation
        E2
    39. caching
      We should try to cache read-only data as much as possible.
      Caching is just as cool and useful as it is dangerous. Watch out, it can backfire.
      resources
      B4
    40. auditing
      As one part of the security aspects, it's important to have auditing so that it's possible to check afterwards who did what when.
      B4
    41. async messaging
      resources
      B3
      code & implementation
      B3
      1. client - server sync
        how to synchronize the client's offline data with the server
        make the synchronization a business - level process rather than a data - level
        process
        resources
        B3
        code & implementation
        B3
      2. batch jobs
        A more efficient solution to the problem would be to think asynchronous messages from the start as often as possible. The batch solution would be kind of built in from the beginning
        resources
        B4

 

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.

 

 

 

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