Migrate from CRUD to DDD - c#

Now I want to try to start from the objects of my model according to the dictates DDD but I have some difficulty in understanding how to migrate my thought patterns because I can not turn the examples that I find lying around on my specific case .
My main concept are the activities , each activity has an indicative code , a description , a status that changes over time and a quarter each Result.
Users want to be able to see the history of all the states hired from the activities, with the dates on which the changes were made . In addition, they also want to be able to create new states, change the description of the existing ones and possibly prevent the use of some of these while maintaining the value for the previous activities .
Each quarter, users want to be able to insert an Result that contains Outcome and recommendations, a rating and the date of formulation of the outcome .
The ratings must be a list freely maintainable by users.
Thinking to my old way I would create classes like this:
public class Activity
{
public int ID;
public string Desc;
public IList<ActivityStatus> ActivityStatusList;
public IList<Result> ResultList;
}
public class ActivityStatus
{
public Activity Activity;
public Status Status;
public DateTime StartDate;
public DateTime EndDate;
}
public class Status
{
public int ID;
public string Desc;
public bool Valid;
}
public class Result
{
public Activity Activity;
public int Quarter;
public string Outcome;
public string Recommendations;
public Rating Rating;
}
public class Rating
{
public int ID;
public string Desc;
public bool Valid;
}
than i will implement a DataAccessLayer mapping this class to a new db (created from this class) with NHibernate and add repository to grant user CRUD operation to all of this object
According to DDD are there better ways?

I'd recommend to read the book or at least the Wikipedia article.
DDD is about focussing on domain logic and modelling this first - in an object-oriented way. Persistence is a technical concern, which should not be the starting point of your design and (usually) not determine, how you will design your domain classes.

If you're eager to code and believe you understand the domain well, I would suggest a BDD test-first approach. Use tools like SpecFlow to describe your business processes in plain english, then gradually fill in the steps and functionality as you go, using mocks, design patterns, inversion of control etc.
Background reading is a must if you're unfamiliar with DDD. Read the book that EagleBeak suggests, get clued up on SOLID principles and experiment yourself.

I can´t tell if there are better ways but what you said would be one way to solve this problem in a DDD fashion.
In my data access layer I typically use an abstract factory of respositories. This way I can plug an specific implementation for data access such as NHibernate.
public interface IRepositoryFactory {
T Repository<T>();
};
public class NHibernateRepositoryFactory {
T Repository<T>() {
..... // find class that implements T in Assemblies with reflection
return repository;
}
};
public static class Persistence {
IRepositoryFactory Factory { get; set; }
};
This way you can call your repository without referencing any specific implementation:
User user = Persistence.Factory.Get<IUserRepository>().FindByEmail("john#tt.com");
user.name = "James";
Persistence.Factory.Get<IUserRepository>().save(user);
Another advantage of using abstract factories for repositories as above is that you can test your code by pluging a fake implementation for the repository.
public class FakeRepositoryFactory {
T Repository<T>() {
..... // find class that implements T in Assemblies of fake repositories
return repository;
}
};
public class FakeUserRepository : public IUserRepository {
User FindByEmail(string email) {
// create mocked user for testing purposes ....
return userMock;
}
};
Your code will not and should not know where the user data is coming from with abstract factories for persistence. This way switch from one way to another can be done in a transparent way.

Related

lazyloading without using lazy<t>

I have:
Category class
public partial class Category : BaseEntity
{
...
public string Name { get; set; }
private ICollection<Discount> _appliedDiscounts;
public virtual ICollection<Discount> AppliedDiscounts
{
get { return _appliedDiscounts ?? (_appliedDiscounts = new List<Discount>()); }
protected set { _appliedDiscounts = value; }
}
}
Service:
public IList<Category> GetCategories()
{
// ado.net to return category entities.
}
public ICollection<Discount> GetDiscount(int categoryId)
{
// ado.net .
}
I don't want to use ORM like EF.. but plain ado.net and i don't want to put in ugly Lazy<T> in my domain definition, for e.g public Lazy....
So how in this case could I get AppliedDiscounts automatically get binded lazy to GetDiscount without using explicitly declaration of Lazy<T> on the Category class ?
I don't know why you don't like the Lazy<T> type - it is simple, useful and you don't have to worry about anything.
And no one forces you to use public Lazy<IEnumerable<Discount>> GetDiscounts();
You could use it internally:
Lazy<IEnumerable<Discount>> discounts = new Lazy<IEnumerable<Discount>>(() => new DiscountCollection());
public IEnumerable<Discount> GetDiscounts()
{
return discounts.Value;
}
It operates as intended - until no one asks for discounts it won't be created.
If you really want - you could create your own implementation. Something like Singleton class in Richter's "CLR via C#" book (because Lazy has all the 'properties' of a proper singleton container - thread safety, only one instance of inner 'singleton' value could be evaluated...).
But do you really want to create it and test? You will just replace a well-designed standard component with a fishy custom one.
AFTER ACTUALLY READING YOUR QUESTION WITH ATTENTION
1) If your lazy loading does not need any thread safety you could accomplish similar behaviour even without any Lazy or complex constructs - just use Func delegate:
public partial class Category : BaseEntity
{
...
private Func<ICollection<Discount>> getDiscounts;
public Category(Func<ICollection<Discount>> getDiscounts) { ... }
public string Name { get; set; }
private ICollection<Discount> _appliedDiscounts;
public virtual ICollection<Discount> AppliedDiscounts
{
get { return _appliedDiscounts ??
(_appliedDiscounts = new List<Discount>(this.getDiscounts())); }
protected set { _appliedDiscounts = value; }
}
}
public IList<Category> GetCategories()
{
// ado.net to return category entities.
... = new Category(() => this.GetDiscount((Int32)curDataObject["categoryId"]))
}
public ICollection<Discount> GetDiscount(int categoryId)
{
// ado.net .
}
If you inject your service it will be even more simple:
public virtual ICollection<Discount> AppliedDiscounts
{
get { return _appliedDiscounts ??
(_appliedDiscounts = new List<Discount>(this.service.GetDiscounts(this.CategoryId))); }
protected set { _appliedDiscounts = value; }
}
2) If you need to use these objects in multiple threads then you will have to redesign your classes - they don't look like threadsafe.
AFTER THE COMMENT
what i want to do is exactly just like this guy
stackoverflow.com/questions/8188546/… . I want to know the concept how
ORM like EF do with the domain, keep it clean and separated from
injecting service class but still able to handle lazy loading. I know
i can use Reflection to get all the object properties and its object
variables(like AppliedDiscounts), but dont' know how to transform
these dynamically to lazy type so that it could be loaded later when
needed.
It is universal principle that you can't get something for nothing. You can't make your entities both clean and separated from any services(even through some proxy), and to allow them to load lazily - if they don't know anything about services and services don't know anything about them then how would the lazy loading work? There is no way to achieve such absolute decoupling(for two components to interact they have to either know about each other, know about some third module-communicator, or some module should know about them. But such coupling could be partially or completely hidden.
Technologies that provide entity object models usually use some of the following techniques:
Code generation to create wrappers(or proxies) above your simple data objects, or solid instances of your interfaces. It could be C# code or IL weaving, well, it could be even an in-memory assembly created dynamically in runtime using something like Reflection.Emit. This is not the easiest or most direct approach, but it will give you enormous code-tuning capabilities. A lot of modern frameworks use it.
Implementation of all those capabilities in Context classes - you won't have the lazy loading in your end objects, you will have to use it explicitly with Context classes: context.Orders.With("OrderDetails"). The positive side is that the entities will be clean.
Injection of service(or only of the needed subset of its operations) - that's what you'd prefer to avoid.
Use of events or some other observer-like pattern - your entities
will be clean from service logic and dependencies(at least in some
sense), but will contain some hookup infrastructure that won't be
very straightforward or easy to manage.
For your custom object model 2 or 3 are the best bets. But you could try 1 with Roslyn

Exposing an object through a 'view' interface

I've been trying to find a flexible way of exposing an object through a 'view'. I'm probably better off explaining by way of example.
I have an Entity Framework entity model, and a web service that can be used to query it. I am able to return the entity classes themselves, but this would include some fields I might not want to share - IDs, for examples, or *Reference properties from any associations in the entity model.
I figure what I need is a view of the data, but I don't particular want to write a view wrapper class for every return type. I'm hoping I'll be able to define an interface and somehow make use of that. For example:
interface IPersonView
{
string FirstName { get; }
string LastName { get; }
}
-
// (Web service method)
IPersonView GetPerson(int id)
{
var personEntity = [...];
return GetView<IPersonView>(personEntity);
}
However, in order to do something like this, I'd have to have my entities implement the view interfaces. I was hoping for a more flexible 'duck-typed' approach as there may be many views of an object, and I don't really to want to have to implement them all.
I've had some success building a dynamic type by reflecting the interface and copying fields and properties across, but I'm not able to cast this back to the interface type in order to get strong typing on the web service.
Just looking for some comments and advice, both would be welcome. Thanks.
You shouldn't ever really be passing entities directly out to a client, they should be used for persistance only. You should introduce DTOs/POCOs tailored to whatever data your API wants to return e.g.
public class PersonDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// public API method
public PersonDto GetPersonApi(int id)
{
var personEntity = // pull entity from db
return new PersonDto()
{
FirstName = personEntity.FirstName,
LastName = personEntity.LastName
};
}
This keeps a clean separation between your persistence layer & public interface. You can use a tool like AutoMapper to do the legwork in terms of mapping the data across. Just setup a mapping once e.g. in your global asax:
protected void Application_Start()
{
Mapper.CreateMap<Person, PersonDto>();
}
...
// public API method
public PersonDto GetPersonApi(int id)
{
var personEntity = // pull entity from db
return Mapper.Map<Person, PersonDto>(personEntity);
}
I typically see this done with AutoMapper or a similar tool. It makes mapping between similar classes much simpler. You still have to create the Views (which in an MVC-context would be a Model), but the most tedious part (the mapping) is taken care of for you so long as you use the same field names.
As a side note, sharing IDs and other reference data will be necessary if you want to update the data, since you'll need to know the keys in order to know which record(s) to update.

Persist Data by Programming Against Interface

I have a IBankAccount interface that I will be passing to the ApplicationService. The changes made on the account objects (in the ApplicationService project) need to be persisted in the database. The repository receives the changes using IBankAccount interface. How can I persist this data into database? This is implemented using LINQ to SQL.
Note: Following is a comment from Scott in http://weblogs.asp.net/scottgu/archive/2007/06/29/linq-to-sql-part-3-querying-our-database.aspx
"Add the interfaces to your LINQ to SQL data model classes. The LINQ to SQL classes are partial classes - which means you could add the interface directly to them."
public class LijosSimpleBankRepository : ILijosBankRepository
{
public System.Data.Linq.DataContext Context
{
get;
set;
}
public virtual void UpdateAccount(DomainInterfaces.IBankAccount iBankAcc)
{
DBML_Project.BankAccount bankAccount;
}
}
namespace DomainInterfaces
{
public interface IBankAccount
{
int BankAccountID { get; set; }
string AccountType { get; set; }
System.Nullable<System.DateTime> OpenedDate { get; set; }
string Status { get; set; }
System.Nullable<int> AccountOwnerID { get; set; }
}
}
namespace DBML_Project
{
public class FixedBankAccount : BankAccount
{
//Note: BankAccount already implemnts IBankAccount
}
public class SavingsBankAccount : BankAccount
{
//Note: BankAccount already implemnts IBankAccount
}
//The auto generated calss is made as abstract
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.BankAccount")]
[InheritanceMapping(Code = "Fixed", Type = typeof(FixedBankAccount), IsDefault = true)]
[InheritanceMapping(Code = "Savings", Type = typeof(SavingsBankAccount))]
public abstract partial class BankAccount : INotifyPropertyChanging, INotifyPropertyChanged, DomainInterfaces.IBankAccount
{
..
}
}
READING
Optimizing Repository’s SubmitChanges Method
How do you abstract out your persistence code when using LINQ to SQL?
LINQ to SQL - mapping exception when using abstract base classes
Your repository should accept BankAccount - not IBankAccount because Linq-to-sql doesn't know what is IBankAccount and compiler doesn't allow you to store it without casting it first to BankAccount (that can obviously fail at runtime if IBankAccount instance is not a BankAccount).
Once you have BankAccount you simply call:
Context.BankAccounts.Add(account);
Context.SubmitChanges();
As far as I understand you need to model a banking system. This mean dealing with bank accounts. This is tough business that is no "Hello World!"-type information technology.
Basically with bank accounts you need to :
Read details (such as account name, value, etc
Debit account
Credit account
Terminate account
Create a new account
... and other operations
The debit and credit operations are the most "transactional" operations of them all since these mean that you'll be editing two accounts at a time and you want to succeed both editings or fail both at once.
This, again, is a risky business since it involves checking a lot of business rules beginning with having enough money on the account (that is not that simple since having an overdraft account means you can go below zero) all the way to ensuring there is a durable transaction that substracts money from one account and adds money to another one.
Also you must check that a person does not try to transfer negative amounts of money because that will be literally stealing money from other accounts. And the list does not stop here. Scott Hanselman worked in a bank for some time and he might be of some help regarding what needs to be checked.
All in all, my response seems to be a "not worthy" one and you might just as well downvote me but, again, the subject is too deep to be covered in a stackoverflow response.
Sorry.

Rich domain model with behaviours and ORM

After watching NDC12 presentation "Crafting Wicked Domain Models" from Jimmy Bogard (http://ndcoslo.oktaset.com/Agenda), I was wandering how to persist that kind of domain model.
This is sample class from presentation:
public class Member
{
List<Offer> _offers;
public Member(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
_offers = new List<Offer>();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public IEnumerable<Offer> AssignedOffers {
get { return _offers; }
}
public int NumberOfOffers { get; private set; }
public Offer AssignOffer(OfferType offerType, IOfferValueCalc valueCalc)
{
var value = valueCalc.CalculateValue(this, offerType);
var expiration = offerType.CalculateExpiration();
var offer = new Offer(this, offerType, expiration, value);
_offers.Add(offer);
NumberOfOffers++;
return offer;
}
}
so there are some rules contained in this domain model:
- Member must have first and last name
- Number of offers can't be changed outside
- Member is responsible for creating new offer, calculating its value and assignment
If if try to map this to some ORM like Entity Framework or NHibernate, it will not work.
So, what's best approach for mapping this kind of model to database with ORM?
For example, how do I load AssignedOffers from DB if there's no setter?
Only thing that does make sense for me is using command/query architecture: queries are always done with DTO as result, not domain entities, and commands are done on domain models. Also, event sourcing is perfect fit for behaviours on domain model. But this kind of CQS architecture isn't maybe suitable for every project, specially brownfield. Or not?
I'm aware of similar questions here, but couldn't find concrete example and solution.
This is actually a very good question and something I have contemplated. It is potentially difficult to create proper domain objects that are fully encapsulated (i.e. no property setters) and use an ORM to build the domain objects directly.
In my experience there are 3 ways of solving this issue:
As already mention by Luka, NHibernate supports mapping to private fields, rather than property setters.
If using EF (which I don't think supports the above) you could use the memento pattern to restore state to your domain objects. e.g. you use entity framework to populate 'memento' objects which your domain entities accept to set their private fields.
As you have pointed out, using CQRS with event sourcing eliminates this problem. This is my preferred method of crafting perfectly encapsulated domain objects, that also have all the added benefits of event sourcing.
Old thread. But there's a more recent post (late 2014) by Vaughn Vernon that addresses just this scenario, with particular reference to Entity Framework. Given that I somehow struggled to find such information, maybe it can be helpful to post it here as well.
Basically the post advocates for the Product domain (aggregate) object to wrap the ProductState EF POCO data object for what concerns the "data bag" side of things. Of course the domain object would still add all its rich domain behaviour through domain-specific methods/accessors, but it would resort to inner data object when it has to get/set its properties.
Copying snippet straight from post:
public class Product
{
public Product(
TenantId tenantId,
ProductId productId,
ProductOwnerId productOwnerId,
string name,
string description)
{
State = new ProductState();
State.ProductKey = tenantId.Id + ":" + productId.Id;
State.ProductOwnerId = productOwnerId;
State.Name = name;
State.Description = description;
State.BacklogItems = new List<ProductBacklogItem>();
}
internal Product(ProductState state)
{
State = state;
}
//...
private readonly ProductState State;
}
public class ProductState
{
[Key]
public string ProductKey { get; set; }
public ProductOwnerId ProductOwnerId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<ProductBacklogItemState> BacklogItems { get; set; }
...
}
Repository would use internal constructor in order to instantiate (load) an entity instance from its DB-persisted version.
The one bit I can add myself, is that probably Product domain object should be dirtied with one more accessor just for the purpose of persistence through EF: in the same was as new Product(productState) allows a domain entity to be loaded from database, the opposite way should be allowed through something like:
public class Product
{
// ...
internal ProductState State
{
get
{
// return this.State as is, if you trust the caller (repository),
// or deep clone it and return it
}
}
}
// inside repository.Add(Product product):
dbContext.Add(product.State);
For AssignedOffers : if you look at the code you'll see that AssignedOffers returns value from a field. NHibernate can populate that field like this: Map(x => x.AssignedOffers).Access.Field().
Agree with using CQS.
When doing DDD first thing, you ignore the persistence concerns. THe ORM is tighlty coupled to a RDBMS so it's a persistence concern.
An ORM models persistence structure NOT the domain. Basically the repository must 'convert' the received Aggregate Root to one or many persistence entities. The Bounded Context matters a lot since the Aggregate Root changes according to what are you trying to accomplish as well.
Let's say you want to save the Member in the context of a new offer assigned. Then you'll have something like this (of course this is only one possible scenario)
public interface IAssignOffer
{
int OwnerId {get;}
Offer AssignOffer(OfferType offerType, IOfferValueCalc valueCalc);
IEnumerable<Offer> NewOffers {get; }
}
public class Member:IAssignOffer
{
/* implementation */
}
public interface IDomainRepository
{
void Save(IAssignOffer member);
}
Next the repo will get only the data required in order to change the NH entities and that's all.
About EVent Sourcing, I think that you have to see if it fits your domain and I don't see any problem with using Event Sourcing only for storing domain Aggregate Roots while the rest (mainly infrastructure) can be stored in the ordinary way (relational tables). I think CQRS gives you great flexibility in this matter.

Wrapping DbSet<TEntity> with a custom DbSet/IDbSet?

First off, I think this is somewhat ridiculous to do but the other members of my team insist upon it and I can't come up with a good argument against it other than "I think it's dumb"...
What we're trying to do is create a completely abstract data layer and then have various implementations of that data layer. Simple enough, right? Enter Entity Framework 4.1...
Our end goal here is that the programmers (I do my best to stay only on the data layer) never want to have to be exposed to the concrete classes. They only ever want to have to use interfaces in their code, aside from obviously needing to instantiate the factory.
I want to achieve something like the following:
First we have our "Common" library of all of the interfaces, we'll call it "Common.Data":
public interface IEntity
{
int ID { get; set; }
}
public interface IUser : IEntity
{
int AccountID { get; set; }
string Username { get; set; }
string EmailAddress { get; set; }
IAccount Account { get; set; }
}
public interface IAccount : IEntity
{
string FirstName { get; set; }
string LastName { get; set; }
DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
}
public interface IEntityFactory
{
DbSet<IUser> Users { get; }
DbSet<IAccount> Accounts { get; }
}
From that we then have an implementation library, we'll call it "Something.Data.Imp":
internal class User : IUser
{
public int ID { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public IAccount Account { get; set; }
public class Configuration : EntityTypeConfiguration<User>
{
public Configuration() : base()
{
...
}
}
}
internal class Account : IAccount
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
public class Configuration : EntityTypeConfiguration<Account>
{
public Configuration() : base()
{
...
}
}
}
Factory:
public class ImplEntityFactory : IEntityFactory
{
private ImplEntityFactory(string connectionString)
{
this.dataContext = new MyEfDbContext(connectionString);
}
private MyEfDbContext dataContext;
public static ImplEntityFactory Instance(string connectionString)
{
if(ImplEntityFactory._instance == null)
ImplEntityFactory._instance = new ImplEntityFactory(connectionString);
return ImplEntityFactory._instance;
}
private static ImplEntityFactory _instance;
public DbSet<IUser> Users // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Users; }
}
public DbSet<IAccount> Accounts // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Accounts; }
}
}
Context:
public class MyEfDataContext : DbContext
{
public MyEfDataContext(string connectionString)
: base(connectionString)
{
Database.SetInitializer<MyEfDataContext>(null);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new User.Configuration());
modelBuilder.Configurations.Add(new Account.Configuration());
base.OnModelCreating(modelBuilder);
}
public DbSet<User> Users { get; set; }
public DbSet<Account> Accounts { get; set; }
}
Then the front-end programmers would be using it such as:
public class UsingIt
{
public static void Main(string[] args)
{
IEntityFactory factory = new ImplEntityFactory("SQLConnectionString");
IUser user = factory.Users.Find(5);
IAccount usersAccount = user.Account;
IAccount account = factory.Accounts.Find(3);
Console.Write(account.Users.Count());
}
}
So that's pretty much it... I'm hoping someone on here might be able to either point me in the right direction or help me out with a good argument that I can fire back at the development team. I've looked at some other articles on this site about EF not being able to work with interfaces and one reply saying that you can't implement IDbSet (which I find kind of curious, why would they provide it if you couldn't implement it?) but so far to no avail.
Thanks in advance for any help!
J
The first argument is that EF doesn't work with interfaces. DbSet must be defined with a real entity implementation.
The second argument is that your entities should not contain DbSet - that is context related class and your entities should be pure of such dependency unless you are going to implement Active record pattern. Even in such case you will definitely not have access to DbSet of different entity in another entity. Even if you wrap set you are still too close to EF and entity never have property accessing all entities of another entity type (not only those related to current instance).
Just to make it clear DbSet in EF has very special meaning - it is not a collection. It is entry point to database (for example each LINQ query on DbSet hits database) and it is in normal scenarios not exposed on entities.
The third argument is that you are using a single context per application - you have a single private instance per singleton factory. Unless you are doing some single run batch application it is definitely wrong.
The last argument is simply practical. You are paid for delivering features not for wasting time on abstraction which doesn't give you (and your customer) any business value. It is not about proving why you should not create this abstraction. It is about proving why you should do it. What value will you get from using it? If your colleagues are not able to come with arguments which have business value you can simply go to your product manager and let him use his power - he holds the budget.
Generally abstraction is part of well designed object oriented application - that is correct. BUT:
Every abstraction will make your application somehow more complex and it will increase cost and time of development
Not every abstraction will make your application better or more maintainable - too much abstraction has reverse effect
Abstracting EF is hard. Saying that you will abstract data access in the way that you can replace it with another implementation is task for data access gurus. First of all you must have very good experience with many data access technologies to be able to define such abstraction which will work with all of them (and in the end you can only tell that your abstraction works with technologies you thought about when you design that). Your abstraction will work only with EF DbContext API and with nothing else because it is not an abstraction. If you want to build universal abstraction you should start studying Repository pattern, Unit of Work pattern and Specification pattern - but that is a big deal of work to make them and to implement them universal. The first step needed is to hide everything related to data access behind that abstraction - including LINQ!
Abstracting data access to support multiple APIs make sense only if you need it now. If you only think that it can be useful in future than it is in business driven projects completely wrong decision and developer who came with that idea is not competent to make business targeting decisions.
When it make sense to do "a lot of" abstraction?
You have such requirement now - that moves burden of such decision to person responsible for budget / project scope / requirements etc.
You need abstraction now to simplify design or solve some a problem
You are doing open source or hobby project and you are not driven by business needs but by purity and quality of your project
You are working on platform (long living retail product which will live for a long time) or public framework - this generally returns to the first point because this type of products usually have such abstraction as requirement
If you are working only targeted application (mostly single purpose applications on demand or outsourced solutions) the abstraction should be used only if necessary. These applications are driven by costs - the target is delivering working solution for minimal costs and in the shortest time. This target must be achieved even if resulting application will not be very good internally - the only thing which matters is if application meets requirements. Any abstraction based on "what if ... happens" or "perhaps we will need ..." increases costs by virtual (non existing) requirements which will in 99% never happen and in most cases initial contract with customer didn't count which such additional costs.
Btw. this type of applications is targeted by MS APIs and designer strategy - MS will make a lot of designers and code generators which will create non optimal but cheap and quick solutions which can be created by people with smaller skill set and are very cheap. The last example is LightSwitch.

Categories

Resources