Blog Home  Home Feed your aggregator (RSS 2.0)  
kevin Mocha - Design
Bookmarks collected from web.
 
 Monday, May 24, 2010

http://randypatterson.com/index.php/2007/09/26/how-to-design-a-fluent-interface/

http://en.wikipedia.org/wiki/Fluent_interface#C.23

#region Fluent Example
 
    public interface IConfigurationFluent
    {
        IConfigurationFluent SetColor(string color);
        IConfigurationFluent SetHeight(int height);
        IConfigurationFluent SetLength(int length);
        IConfigurationFluent SetDepth(int depth);
    }
 
    public class ConfigurationFluent : IConfigurationFluent
    {
        string color;
        int height;
        int length;
        int depth;
 
        public IConfigurationFluent SetColor(string color)
        {
            this.color = color;
            return this;
        }
 
        public IConfigurationFluent SetHeight(int height)
        {
            this.height = height;
            return this;
        }
 
        public IConfigurationFluent SetLength(int length)
        {
            this.length = length;
            return this;
        }
 
        public IConfigurationFluent SetDepth(int depth)
        {
            this.depth = depth;
            return this;
        }
    }
 
    #endregion
 
    public class ExampleProgram
    {
        public static void Main(string[] args)
        {
            //Standard Example
            IConfiguration config = new Configuration
            {
                Color = "blue",
                Height = 1,
                Length = 2,
                Depth = 3
            };
 
            //Fluent Example
            IConfigurationFluent fluentConfig =
                  new ConfigurationFluent().SetColor("blue")
                                           .SetHeight(1)
                                           .SetLength(2)
                                           .SetDepth(3);
        }
    }
Monday, May 24, 2010 3:32:43 PM UTC  #    Comments [0]    |   |  Trackback
 Wednesday, April 07, 2010

http://stackoverflow.com/questions/2056/what-are-mvp-and-mvc-and-what-is-the-difference

Model-View-Presenter

In MVP, the Presenter contains the the UI business logic for the View. All invocations from the View delegate directly to Presenter. The Presenter is also decoupled directly from the View and talks to it through an interface. This is to allow mocking of the View in a unit test. One common attribute of MVP is that there has to be a lot of two-way dispatching. For example, when someone clicks the "Save" button, the event handler delegates to the Presenter's "OnSave" method. Once the save is completed, the Presenter will then call back the View through it's interface so that the View can display that the save has completed.

MVP tends to be a very natural pattern for achieving separated presentation in Web Forms. The reason is because the View is always created first by the ASP.NET runtime. You can find out more about both variants.

Two primary variations

Passive View: The View is as as dumb as possible and contains almost zero logic. The Presenter is a middle man that talks to the View and the Model. The View and Model are completely shielded from one another. The Model may raise events, but the Presenter subscribes to them for updating the View. In Passive View there is no direct data binding, instead the View exposes setter properties which the Presenter uses to set the data. All state is managed in the Presenter and not the View.

  • Pro: maximum testability surface; clean separation of the View and Model
  • Con: more work (for example all the setter properties) as you are doing all the data binding yourself.

Supervising Controller: The Presenter handles user gestures. The View binds to the Model directly through data binding. In this case it's the Presenter's job to pass off the Model to the View so that it can bind to it. The Presenter will also contain logic for gestures like pressing a button, navigation, etc.

  • Pro: by leveraging databinding the amount of code is reduced.
  • Con: there's less testable surface (because of data binding), and there's less encapsulation in the View since it talks directly to the Model.

Model-View-Controller

In the MVC, the Controller is responsible for determining which View is displayed in response to any action including when the application loads. This differs from MVP where actions route through the View to the Presenter. In MVC, every action in the View correlates with a call to a Controller along with an action. In the web each action involves a call to a URL on the other side of which there is a Controller who responds. Once that Controller has completed it's processing, it will return the correct View. The sequence continues in that manner throughout the life of the application:

    Action in the View
        -> Call to Controller
        -> Controller Logic
        -> Controller returns the View.

One other big difference about MVC is that the View does not directly bind to the Model. The view simply renders, and is completely stateless. In implementations of MVC the View usually will not have any logic in the code behind. This is contrary to MVP where it is absolutely necessary as if the View does not delegate to the Presenter, it will never get called. (lulu: That means the view has to have the delegate code in MVP)

There is a MSDN article about the Presentation Model and a section in the Composite Application Guidance for WPF (former Prism) about Separated Presentation Patterns

Presentation Model

One other pattern to look at is the Presentation Model pattern. In this pattern there is no Presenter. Instead the View binds directly to a Presentation Model. The Presentation Model is a Model crafted specifically for the View. This means this Model can expose properties that one would never put on a domain model as it would be a violation of separation-of-concerns. In this case, the Presentation Model binds to the domain model, and may subscribe to event coming from that Model. The View then subscribes to events coming from the Presentation Model and updates itself accordingly. The Presentation Model can expose commands which the view uses for invoking actions. The advantage of this approach is that you can essentially remove the code-behind altogether as the PM complete encapsulates all of the behaviour for the view. This pattern is a very strong candidate for use in WPF applications and is also called Model-View-ViewModel.

 

 

More links about this:

 

http://www.aspiringcraftsman.com/2007/08/interactive-application-architecture/

(lulu: traditional MVC)

http://www.aspiringcraftsman.com/wordpress/wp-content/uploads/2007/08/MVC1.png

The View’s responsibility can be seen as primarily dealing with output while the Controller’s responsibility can be seen as primarily dealing with input. It is the shared responsibility of both the View and the Controller to interact with the Model. The Controller interacts with the Model as the result of responding to user input, while the View interacts with the Model as the result of updates to itself. Both may access and modify data within the Model as needed.

As data is entered by the user, the Controller intercepts the user’s input and responds appropriately. Some user actions will result in interaction with the Model, such as changing data or invoking methods, while other user actions may result in visual changes to the View, such as the collapsing of menus, the highlighting of scrollbars, etc.

MVC Misconceptions

One common misconception about the relationship between the MVC components is that the purpose of the Controller is to separate the View from the Model. While the MVC pattern does decouple the application’s domain layer from presentation concerns, this is achieved through the Observer Pattern, not through the Controller. The Controller was conceived as a mediator between the end user and the application, not between the View and the Model.

 

 


http://haacked.com/archive/2008/06/16/everything-you-wanted-to-know-about-mvc-and-mvp-but.aspx

(lulu: IN current MVC, the view will not get data from Model directly)

The two patterns are similar in that they both are concerned with separating concerns and they both contain Models and Views. Many consider the MVP pattern to simply be a variant of the MVC pattern. The key difference is suggested by the problem that the MVP pattern sought to solve with the MVP pattern. Who handles the user input?

With MVC, it’s always the controller’s responsibility to handle mouse and keyboard events. With MVP, GUI components themselves initially handle the user’s input, but delegate to the interpretation of that input to the presenter. This has often been called “Twisting the Triad”, which refers to rotating the three elements of the MVC triangle and replacing the “C” with “P” in order to get MVP.

Wednesday, April 07, 2010 9:00:38 PM UTC  #    Comments [0]    |  Trackback
 Sunday, April 04, 2010

The whole point of bringing in an IoC container is that you can use it to eliminate hard-coded
dependencies between components.

 

Using an IoC Container

An IoC container is a standard software component that supports and simplifies IoC. It lets
you register a set of components (i.e., abstract types and your currently chosen concrete
implementations), and then handles the business of instantiating them. You can configure
and register components either with an XML file or with C# code (or both).

At runtime, you can call a method similar to container.Resolve(Type type), where
type could be a particular interface or abstract type or a particular concrete type, and the
container will return an object satisfying that type definition, according to whatever concrete
type is configured. It sounds trivial, but a good IoC container adds three extra clever features:

Dependency chain resolution: If you request a component that itself has dependencies
(e.g., constructor parameters), the container will satisfy those dependencies recursively,
so you can have component A, which depends on B, which depends on C, and so on. In
other words, you can forget about the wiring on your component circuit board—just
think about the components, because wiring happens magically.

Object lifetime management: If you request component A more than once, should you get
the same actual instance of A each time, or a fresh new instance each time? The container
will usually let you configure the “lifestyle” of a component, allowing you to select from
predefined options including singleton (the same instance each time), transient (a new
instance each time), instance-per-thread, instance-from-a-pool
, and so on.

Explicit constructor parameter values configuration: For example, if the constructor for
MembersRepository demands a string called connectionString, (as ours did earlier), you
can configure a value for it in your XML config file. It’s a crude but simple configuration
system that removes any need for your code to pass around connection strings, SMTP
server addresses, and so on.
So, in the preceding example, you’d configure MembersRepository as the active concrete
implementation for IMembersRepository. Then, when some code calls container.Resolve
(typeof(AdminController)), the container will figure out that to satisfy AdminController’s
constructor parameters it first needs an object implementing IMembersRepository. It will
get one according to whatever concrete implementation you’ve configured (in this case,
MembersRepository), supplying the connectionString you’ve configured. It will then use that to
instantiate and return an AdminController.

Sunday, April 04, 2010 9:34:04 PM UTC  #    Comments [0]    |  Trackback

Model-view-presenter (MVP) is a recent variation on MVC that’s designed to fit more easily
with stateful GUI platforms such as Windows Forms or ASP.NET WebForms. You don’t need to
know about MVP when you’re using ASP.NET MVC, but it’s worth explaining what it is so you
can avoid confusion.

In this twist, the presenter has the same responsibilities as MVC’s controller, plus it also
takes a more hands-on relationship to the stateful view, directly editing the values displayed
in its UI widgets according to user input (instead of letting the view render itself from a template).
There are two main flavors:

• Passive view, in which the view contains no logic, and merely has its UI widgets manipulated
by the presenter.

• Supervising controller, in which the view may be responsible for certain presentation
logic, such as data binding, having been given a reference to some data source in the
model.

The difference between the two flavors is quite subjective and simply relates to how
intelligent the view is allowed to be. Either way, the presenter is decoupled from the GUI
technology, so its logic can be followed easily and is suitable for automated testing

image

In this architecture, requests are routed to a controller class, which processes user input
and works with the domain model to handle the request. While the domain model holds
domain logic (i.e., business objects and rules), controllers hold application logic, such as navigation
through a multistep process or technical details like authentication. When it’s time to
produce a visible UI for the user, the controller prepares the data to be displayed (the presentation
model, or ViewData in ASP.NET MVC, which for example might be a list of Product
objects matching the requested category), selects a view, and leaves it to complete the job.
Since controller classes aren’t coupled to the UI technology (HTML), they are just pure,
testable application logic.

Sunday, April 04, 2010 9:25:02 PM UTC  #    Comments [0]    |   |  Trackback
 Thursday, March 25, 2010

From book “Code leader using people tools and processes to build successful software”

image image 

image

 

The trickiest part of the MVP design process is the View. It must represent all of the interaction you will
have with your user, using display-agnostic data types. The View, in essence, forms your application’s
contract with what is ‘‘on the glass’’ or visible to the user on their monitor. If you are following a TDD
development process, your View is likely to change and evolve during the course of development, as
requirements become more apparent. That should be easy to do if the proper separation between View
and Presenter is maintained, although a little refactoring along the way never hurt anyone.

In most languages, it is easiest to represent your View as an interface. The concrete class directly responsible
for display will implement the View interface. When you write your test code, you can create another
implementation of the View interface for testing purposes that has no actual user interface elements
associated with it.

There is one major decision to make before starting work on your View interface. Will your View expose
events directly? Or will it call the Presenter to report user activity? This is often debated when starting an
MVP project, and there are adherents in both camps. To put the cards on the table up front, I personally
favor the former from an architectural perspective. It offers the cleanest separation between View and
Presenter because the View need know nothing at all about the Presenter. It only receives data pushed to
it and fires events that represent user actions. From a practical standpoint, however, there are cons. Using
events may be difficult in some implementation environments. Specifically in a web application, it may
be difficult for your server ‘‘page’’ to fire events, and just as difficult for your Presenter to subscribe to
them. It can be much easier in such an application to provide the View with direct access to the Presenter
so that user events can be reported directly as method calls. That potentially makes it easier to deal with
the issue of display-agnostic data types as well. If your View’s user interface element (a button, say) fires
events, and the View has to catch those events, translate from display data types to neutral data types,
and then fire a second event, the code could become quite cumbersome.

 

image

 

Method 1

 

   1:  public interface ISurveyView
   2:  {
   3:      List<string> Users { get; set; }
   4:      bool Question1 { get; set; }
   5:      string Question2 { get; set; }
   6:  }
   7:  public class SurveyPresenter
   8:  {
   9:      private static Dictionary<ISurveyView, SurveyPresenter> _presenters =
  10:      new Dictionary<ISurveyView, SurveyPresenter>();
  11:      private static readonly object lockObject = new object();
  12:      public static SurveyPresenter Instance(ISurveyView view)
  13:      {
  14:          lock (lockObject)
  15:          {
  16:              if (!_presenters.ContainsKey(view))
  17:                  _presenters[view] = new SurveyPresenter(view);
  18:              return _presenters[view];
  19:          }
  20:      }
  21:      ISurveyView _view;
  22:      private SurveyPresenter(ISurveyView view)
  23:      {
  24:          _view = view;
  25:      }
  26:      public void OnLoad()
  27:  {
  28:  //this is where you would go to the
  29:  //model for data, but we’ll cheat
  30:  List<string> users = new List<string>(new string[] i
  31:  { "Fred", "Bob", "Patty" });
  32:  _view.Users = users;
  33:  }
  34:      public void SelectedIndexChanged(int index)
  35:      {
  36:          //go to the model and get answers for questions
  37:          //we’ll make it up
  38:          //this is also where the answers to the previous
  39:          //questions would be saved back to the model
  40:          _view.Question1 = true;
  41:          _view.Question2 = string.Format("{0} is cool!", _view.Users[index]);
  42:      }
  43:  }
  44:   
  45:  public partial class MvpMain : Form, ISurveyView
  46:  {
  47:      public MvpMain()
  48:      {
  49:          InitializeComponent();
  50:      }
  51:      private SurveyPresenter _presenter;
  52:      #region ISurveyView Members
  53:      public List<string> Users
  54:      {
  55:          get
  56:          {
  57:              List<string> users = new List<string>();
  58:              foreach (object item in userList.Items)
  59:              {
  60:                  users.Add((string)item);
  61:              }
  62:              return users;
  63:          }
  64:          set
  65:          {
  66:              userList.Items.Clear();
  67:              foreach (string user in value)
  68:              {
  69:                  userList.Items.Add(user);
  70:              }
  71:          }
  72:      }
  73:      public bool Question1
  74:      {
  75:          get
  76:          {
  77:              if (yesButton.Checked)
  78:                  return true;
  79:              else
  80:                  return false;
  81:          }
  82:          set
  83:          {
  84:              if (value)
  85:              {
  86:                  yesButton.Checked = true;
  87:                  noButton.Checked = false;
  88:              }
  89:              else
  90:              {
  91:                  yesButton.Checked = false;
  92:                  noButton.Checked = true;
  93:              }
  94:          }
  95:      }
  96:      public string Question2
  97:      {
  98:          get
  99:          {
 100:              return question2Box.Text;
 101:          }
 102:          set
 103:          {
 104:              question2Box.Text = value;
 105:          }
 106:      }
 107:      #endregion
 108:      private void MvpMain_Load(object sender, EventArgs e)
 109:      {
 110:          _presenter = SurveyPresenter.Instance(this);
 111:          _presenter.OnLoad();
 112:      }
 113:      private void userList_SelectedIndexChanged(object sender, EventArgs e)
 114:      {
 115:          _presenter.SelectedIndexChanged(userList.SelectedIndex);
 116:      }
 117:  }

 

Method 2

   1:  public interface ISurveyView
   2:  {
   3:      List<string> Users { get; set; }
   4:      bool Question1 { get; set; }
   5:      string Question2 { get; set; }
   6:      event SelectionChangedDelegate SelectionChanged;
   7:      event OnLoadDelegate OnLoad;
   8:  }
   9:  public delegate void SelectionChangedDelegate(int index);
  10:  public delegate void OnLoadDelegate();
  11:   
  12:  public class SurveyPresenter
  13:  {
  14:      ISurveyView _view;
  15:      public SurveyPresenter(ISurveyView view)
  16:  {
  17:  _view = view;
  18:  _view.OnLoad += new OnLoadDelegate(OnLoad);
  19:  _view.SelectionChanged += new i
  20:  SelectionChangedDelegate(SelectedIndexChanged);
  21:  }
  22:      public void OnLoad()
  23:  {
  24:  //this is where you would go to the
  25:  //model for data, but we’ll cheat
  26:  List<string> users = new List<string>(new string[] i
  27:  { "Fred", "Bob", "Patty" });
  28:  _view.Users = users;
  29:  }
  30:      public void SelectedIndexChanged(int index)
  31:      {
  32:          //go to the model and get answers for questions
  33:          //we’ll make it up
  34:          //This is also where the answers to the previous
  35:          //questions would be saved back to the model.
  36:          _view.Question1 = true;
  37:          _view.Question2 = string.Format("{0} is cool!", _view.Users[index]);
  38:      }
  39:  }
  40:  public partial class MvpMain : Form, ISurveyView
  41:  {
  42:      public MvpMain()
  43:      {
  44:          InitializeComponent();
  45:          _presenter = new SurveyPresenter(this);
  46:      }
  47:      private SurveyPresenter _presenter;
  48:      #region ISurveyView Members
  49:      public List<string> Users
  50:      {
  51:          get
  52:          {
  53:              List<string> users = new List<string>();
  54:              foreach (object item in userList.Items)
  55:              {
  56:                  users.Add((string)item);
  57:              }
  58:              return users;
  59:          }
  60:          set
  61:          {
  62:              userList.Items.Clear();
  63:              foreach (string user in value)
  64:              {
  65:                  userList.Items.Add(user);
  66:              }
  67:          }
  68:      }
  69:      public bool Question1
  70:      {
  71:          get
  72:          {
  73:              if (yesButton.Checked)
  74:                  return true;
  75:              else
  76:                  return false;
  77:          }
  78:          set
  79:          {
  80:              if (value)
  81:              {
  82:                  yesButton.Checked = true;
  83:                  noButton.Checked = false;
  84:              }
  85:              else
  86:              {
  87:                  yesButton.Checked = false;
  88:                  noButton.Checked = true;
  89:              }
  90:          }
  91:      }
  92:      public string Question2
  93:      {
  94:          get
  95:          {
  96:              return question2Box.Text;
  97:          }
  98:          set
  99:          {
 100:              question2Box.Text = value;
 101:          }
 102:      }
 103:      public event OnLoadDelegate OnLoad;
 104:      public event SelectionChangedDelegate SelectionChanged;
 105:      #endregion
 106:      private void MvpMain_Load(object sender, EventArgs e)
 107:      {
 108:          if (OnLoad != null)
 109:              OnLoad();
 110:      }
 111:      private void userList_SelectedIndexChanged(object sender, EventArgs e)
 112:      {
 113:          if (SelectionChanged != null)
 114:              SelectionChanged(userList.SelectedIndex);
 115:      }
 116:  }
Thursday, March 25, 2010 8:56:58 PM UTC  #    Comments [0]    |   |  Trackback
 Tuesday, March 09, 2010

http://en.wikipedia.org/wiki/Component-oriented_programming

The main idea is separation of concerns;

Software engineers regard components as part of the starting platform for service orientation. Components play this role, for example, in Web Services, and more recently, in Service-Oriented Architecture (SOA) - whereby a component is converted[by whom?] into a service and subsequently inherits further characteristics beyond that of an ordinary component.

An individual component is a software package or a module that encapsulates a set of related functions (or data).

All system processes are placed into separate components so that all of the data and functions inside each component are semantically related (just as with the contents of classes). Because of this principle, it is often said that components are modular and cohesive.

With regard to system-wide co-ordination, components communicate with each other via interfaces. When a component offers services to the rest of the system, it adopts a provided interface which specifies the services that can be utilized by other components and how. This interface can be seen as a signature of the component - the client does not need to know about the inner workings of the component (implementation) in order to make use of it. This principle results in components referred to as encapsulated.

Another important attribute of components is that they are substitutable,

Software components often take the form of objects or collections of objects (from object-oriented programming), in some binary or textual form, adhering to some interface description language (IDL) so that the component may exist autonomously from other components in a computer.

Reusability is an important characteristic of a high-quality software component. A software component should be designed and implemented so that it can be reused in many different programs.

It takes significant effort and awareness to write a software component that is effectively reusable. The component needs to be:

  • fully documented
  • thoroughly tested
    • robust - with comprehensive input-validity checking
    • able to pass back appropriate error messages or return codes
  • designed with an awareness that it will be put to unforeseen uses

Differences from object-oriented programming

Proponents of object-oriented programming (OOP) maintain that software should be written according to a mental model of the actual or imagined objects it represents. OOP and the related disciplines of object-oriented design and object-oriented analysis focus on modeling real-world[citation needed] interactions and attempting to create "verbs" and "nouns" which can be used in intuitive[citation needed] ways, ideally by end users as well as by programmers coding for those end users.

Component-based software engineering, by contrast, makes no such assumptions, and instead states that developers should construct software by gluing together prefabricated components - much like in the fields of electronics or mechanics. Some peers[who?] will even talk of modularizing systems as software components as a new programming paradigm.

 

 

 

Component-based development (CBD) is an extension of object-oriented programming. CBD does away with the language and vendor-specific limitations of OOP, and makes software reuse more practical and accelerates the development process. Event-based programming is the next logical step in CBD, and makes components more reusable due to their decoupled nature. But event-based systems are easier to develop, which means they are cheaper and more reliable than traditional OOP or CBD systems.

Tuesday, March 09, 2010 7:22:24 PM UTC  #    Comments [0]    |   |  Trackback
 Monday, January 25, 2010

(By Eric Evan)

Chapter 1 What Is Domain-Driven Design

When we begin a software project, we should focus on the domain it is operating in. The entire purpose of the software is to enhance a specific domain.

How can we make the software fit harmoniously with the domain? The best way to do it is to make software a reflection of the domain.

The model is our internal representation of the target domain, and it is very necessary throughout the design and the development process.

There are different approaches to software design. One is the waterfall design method. This method involves a number of stages. The business experts put up a set of requirements which are communicated to the business analysts. The analysts create a model based on those requirements, and pass the results to the developers, who start coding based on what they have received. It’s a one way flow of knowledge. While this has been a traditional approach in software design, and has been used with a certain level of success over the years, it has its flaws and limits. The main problem is that there is no feedback from the analysts to the business experts or from the developers to the analysts. Another approach is the Agile methodologies, such as Extreme Programming (XP). These methodologies are a collective movement against the waterfall approach, resulting from the difficulties of trying to come up with all the requirements upfront, particularly in light of requirements change. It’s really hard to create a complete model which covers all aspects of a domain upfront. It takes a lot of thinking, and often you just cannot see all the issues involved from the beginning, nor can you foresee some of the negative side effects or mistakes of your design. Another problem Agile attempts to solve is the so called “analysis paralysis”, with team members so afraid of making any design decisions that they make no progress at all. While Agile advocates recognize the importance of design decision, they resist upfront design. Instead they employ a great deal of implementation flexibility, and through iterative development with continuous business stakeholder participation and a lot of refactoring, the development team gets to learn more about the customer domain and can better produce software that meets the customers needs.

 

The Agile methods have their own problems and limitations; they advocate simplicity, but everybody has their own view of what that means. Also, continuous refactoring done by developers without solid design principles will produce code that is hard to understand or change. And while the waterfall approach may lead to over-engineering, the fear of overengineering may lead to another fear: the fear of doing a deep, thoroughly thought out design.

 

Chapter 2 The Ubiquitous Language

A core principle of domain-driven design is to use a language based on the model. Since the model is the common ground, the place where the software meets the domain, it is appropriate to use it as the building ground for this language.

Building a language like that has a clear outcome: the model and the language are strongly interconnected with one another. A change in the language should become a change to the model.

 

 

Chapter 3 Model-Driven Design

A better approach is to closely relate domain modeling and design. The model should be constructed with an eye open to the software and design considerations. Developers should be included in the modeling process.

 

image

 

image

 

 

image

 

Entities: There is a category of objects which seem to have an identity, which remains the same throughout the states of the software. For these objects it is not the attributes which matter, but a thread of continuity and identity, which spans the life of a system and can extend beyond it. Such objects are called Entities.

 

Value Objects:  There are cases when we need to contain some attributes of a domain element. We are not interested in which object it is, but what attributes it has. An object that is used to describe certain aspects of a domain, and which does not have identity, is named Value Object.

It is highly recommended that value objects be immutable.
One golden rule is: if Value Objects are shareable, they should be immutable. Value Objects should be kept thin and simple. When a Value Object is needed by another party, it can be simply passed by value, or a copy of it can be created and given.

 

Services:

we discover that some aspects of the domain are not easily mapped to objects.  But there are some actions in the domain, some verbs, which do not seem to belong to any object. They represent an important behavior of the domain, so they cannot be neglected or simply incorporated into some of the Entities or Value Objects. When such a behavior is recognized in the domain, the best practice is to declare it as a Service. Such an object does not have an internal state, and its purpose is to simply provide functionality for the domain. The assistance provided by a Service can be a significant one, and a Service can group related functionality which serves the Entities and the Value Objects.

(For example, to transfer money from one account to another; should that function be in the sending account or the receiving account? It feels just as misplaced in either.)

There are three characteristics of a Service:
1. The operation performed by the Service refers to a domain concept which does not naturally belong to an Entity or Value
Object.
2. The operation performed refers to other objects in the domain.
3. The operation is stateless.

 

Modules: it is necessary to organize the model into modules. Modules are used as a method of organizing related concepts and tasks in order to reduce complexity.

Another reason for using modules is related to code quality. It is widely accepted that software code should have a high level of cohesion and a low level of coupling.

Two of the most used are communicational cohesion and functional cohesion.

 

 

Three patterns:  Aggregate is a domain pattern used to define object ownership and boundaries. Factories and Repositories are two design patterns which help us deal with object creation and storage.

 

An Aggregate is a group of associated objects which are considered as one unit with regard to data changes.

 

The root is an Entity, and it is the only object accessible from outside. The root can hold references to any of the aggregate objects, and the other objects can hold references to each other, but an outside object can hold references only to the root object.

Cluster the Entities and Value Objects into Aggregates and define boundaries around each. Choose one Entity to be the root of each Aggregate, and control all access to the objects inside the boundary through the root. Allow external objects to hold references to the root only. Transient references to internal members can be passed out for use within a single operation only.

 

Factories are used to encapsulate the knowledge necessary for object creation, and they are especially useful to create Aggregates. When the root of the Aggregate is created, all the objects contained by the Aggregate are created along with it, and all the invariants are enforced.
A Factory Method is an object method which contains and hides knowledge necessary to create another object.

 

There are times when a Factory is not needed, and a simple constructor is enough. Use a constructor when:
• The construction is not complicated.
• The creation of an object does not involve the creation of others, and all the attributes needed are passed via the constructor.
• The client is interested in the implementation, perhaps wants to choose the Strategy used.
• The class is the type. There is no hierarchy involved, so no need to choose between a list of concrete implementations.

 

 

 

Therefore, use a Repository, the purpose of which is to encapsulate all the logic needed to obtain object references.

The overall effect is that the domain model is decoupled from the need of storing objects or their references, and accessing the
underlying persistence infrastructure. Provide repositories only for Aggregate roots that actually need direct access. Keep the client focused on the model, delegating all object storage and access to the Repositories.

 

There is a relationship between Factory and Repository. They are both patterns of the model-driven design, and they both help us to manage the life cycle of domain objects. While the Factory is concerned with the creation of objects, the Repository takes care of already existing objects.

 

Chapter 4 Refactoring Toward Deeper Insight

 

One of the first things we are taught about modeling is to read the business specifications and look for nouns and verbs. The nouns are converted to classes, while the verbs become methods. This is a simplification, and will lead to a shallow model.

We start with a coarse, shallow model. Then we refine it and the design based on deeper knowledge about the domain, on a better understanding of the concerns. We add new concepts and abstractions to it. The design is then refactored. Each refinement adds more clarity to the design. This creates in turn the premises for a Breakthrough.

 

To reach a Breakthrough, we need to make the implicit concepts explicit.

The first way to discover implicit concepts is to listen to the language.

Try to see if there is a missing concept.

 

Another obvious way of digging out model concepts is to use domain literature.

 

There are other concepts which are very useful when made explicit: Constraint, Process and Specification.

Placing the Constraint into a separate method has the advantage of making it explicit.
Processes are usually expressed in code with procedures.
Simply said, a Specification is used to test an object to see if it satisfies a certain criteria. The domain layer contains business rules which are applied to Entities and Value Objects. Those rules are usually incorporated into the objects they apply to. When rule is not a simple method and spans many entities and value objects,  the rule should be encapsulated into an object of its own, which becomes the Specification of the Customer, and should be kept in the domain layer.

 

 

Chapter 5 Preserving Model Integrity

 

This chapter is about large projects which require the combined efforts of multiple teams.

 

Instead of trying to keep one big model that will fall apart later, we should consciously divide it into several models.

Each model should have a clearly delimited border, and the relationships between models should be defined with precision.

 

image

 

A model should be small enough to be assigned to one team.

 

Bounded Context: The main idea is to define the scope of a model, to draw up the boundaries of its context, then do the most possible to keep the model unified.
Explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don’t be distracted or confused by issues outside.

A Bounded Context is not a Module. A Bounded Context provides the logical frame inside of which the model evolves. Modules are used to organize the elements of a model, so Bounded Context encompasses the Module.

 

A Context Map is a document which outlines the different Bounded Contexts and the relationships between them. What it is important is that everyone working on the project shares and understands it.

 

A common practice is to define the contexts, then create modules for each context, and use a naming convention to indicate the context each module belongs to.

 

The purpose of the Shared Kernel is to reduce duplication, but still keep two separate contexts.

 

Core Domain and Generic Subdomain

 

Last Chapter

 

Keep in mind some of the pitfalls of domain modeling:
1) Stay hands-on. Modelers need to code.
2) Focus on concrete scenarios. Abstract thinking has to be anchored in concrete cases.
3) Don't try to apply DDD to everything. Draw a context map and decide on where you will make a push for DDD and where you will not. And then don't worry about it outside those boundaries.
4) Experiment a lot and expect to make lots of mistakes. Modeling is a creative process.

Monday, January 25, 2010 9:54:21 PM UTC  #    Comments [0]    |   |  Trackback
 Monday, April 21, 2008
 Tuesday, April 08, 2008
 Monday, January 07, 2008
 Tuesday, October 16, 2007
 Monday, October 15, 2007

Chapter 1:

There are three legs that hold up every implementation of empirical process control: visibility, inspection, and adaptation.

I've limited my enumeration of complexity in software development to the three most significant dimensions: requirements, technology, and people.

image

The skeleton operates this way: At the start of an iteration, the team reviews what it must do. It then selects what it believes it can turn into an increment of potentially shippable functionality by the end of the iteration. The team is then left alone to make its best effort for the rest of the iteration. At the end of the iteration, the team presents the increment of functionality it built so that the stakeholders can inspect the functionality and timely adaptations to the project can be made.

The heart of Scrum lies in the iteration. The team takes a look at the requirements, considers the available technology, and evaluates its own skills and capabilities. It then collectively determines how to build the functionality, modifying its approach daily as it encounters new complexities, difficulties, and surprises. The team figures out what needs to be done and selects the best way to do it. This creative process is the heart of the Scrum's productivity.

There are only three Scrum roles: the Product Owner, the Team, and the ScrumMaster.           "Ham and Eggs!"

 

image

  1. Monthly Sprint planning meeting
  2. Daily Scrum meeting
  3. monthly Sprint review meeting
  4. Sprint retrospective meeting

image

 

image

image

Tasks should be divided so that each takes roughly 4 to 16 hours to finish. Tasks longer than 4 to 16 hours are considered mere placeholders for tasks that haven't yet been appropriately defined.

Monday, October 15, 2007 10:20:32 PM UTC  #    Comments [0]    |   |  Trackback
Copyright © 2010 Kevin Mocha. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: