Saturday, May 30, 2015

New features in Attracs Bold

It is very easy to believe that Bold for Delphi is dead and the best action is to leave Delphi and just port your existing applications to some other platforms like C#.

I would like to inform that Attracs version of Bold is very actively developed.
Beside all small bug fixes and changes this is some bigger improvements.
Thanks to our skilled consultants that made it possible.

Autosubscription. 
You do not need to call DefaultSubscribe in derived code. Bold handle that automatically resulting in cleaner code.

No hash lookup for datatypes
Internally Bold now call hash lookups for datatypes. This is fast but when done frequently the time will add up. Attracs version use hardcoded datatypes instead as this changes very seldom or never. Together with some other optimization Bold can now handle about twice as many objects per second.

Developer Express grid and editors is boldaware
Not much to say about that. Much nicer components than the original in Bold

Caching of OCL result
Boldaware components evaluate OCL expressions when size of component is changed. For grids this is done for all cells. Using a cache is more effective.

Spanfetch avoid lazyfetch
In Bold it is very easy to trigger a lazy fetch of data. This means that one SQL statement is generated each time data is needed. This can be merged to one final SQL per table that is more effective. So this means a parsing of OCL and calculate the most effective SQL from that. Now there is even support for OCL variables but still a bit unstable. A very powerful and complicated addition to Bold.

ViewModels
When you have a many Bold-handles on a form it is easy to make a mess. Viewmodel is a new component that collect the handles in a nice treeview. It have also some other features so very little code is required on forms. In some cases no code at all. Less code also means less chances for bugs.

LogServer
This is the latest feature. Usually we log to a plain text-file. But that means a lot of information is lost. Because then we need to parse raw text to get information like performance, frequency of events, exceptions etc. Log to a database is better because it is more structured. Data is saved on the proper place.
This also means we can log more as it is easy to find data with SQL and diskspace is cheap. We log all user actions to a database by intercept events also from timers etc. We can also log all modifications of objects. The log can contain time, user, value etc. Hopefully this means much better chance to reproduce those random bugs in live environment.

Tuesday, May 6, 2014

Voices from the petition

I just want to highlight some of the comments from petition.


  • I am looking for MDD framework for delphi, there is none like Bold. Other frameworks are just in its infancy. Please release Bold source.
  • We need sources for certification.
  • I use it for development and is stuck with Delphi 5...
  • As Developer find no support/update for Bold
  • We need a good framework like BOLD in this language. Release it as opensource , so a new guy in Delphi like me could use it and the community can improve it. It'll be an advantage for Delphi.
  • I am used this framework. And I liked it/
  • Trying to resurrect old code in D7 that needs this ancient software.
  • I like this Framework. Let go Bold it's way.
  • We've a lot good old apps using bold as it's main technologie and to be up-to-date, we had to rewritte all things from scratch...which is a very bad idea...(time consuming). Bold as opensource and compatible with the latest version of Delphi (unicode) would be a great step into the future...
  • I have products that sadly still cannot be upgraded to current Delphi from d7.
  • We are short of tools like Bold
  • Want to invest in learning this MDA framework, since it is the only one I know that actually succeeds in raising the abstraction level of the design work.
  • I have developed Bold Applications that are now locked into Delphi 7. If there is no future to Bold these systems will be moved to Visual Studio with ECO and I will be leaving the team.
  • I write an application which depends on Bold and cannot upgrade to XE2 because the work in re-writing the application without Bold is too large.

So obviously there is still a huge interest for Bold. 194 users signed petitions.

Wednesday, December 4, 2013

A hint how to use collect in OCL

Sometimes I want to merge several list into one big list. Consider this OCL expression

WorkPool.allinstances.buffInProcess->union(WorkPool.allinstances.buffopenplans)->union(Workpool.allinstances.buffforwarded)

So in this case Workpool contain some buffers or multilinks. I want to merge 3 multilinks into one list.
It can be done with collect.

WorkPool.allinstances->collect(buffInProcess->union(buffopenplans)->union(buffforwarded))

The result is exact the same but you do not need to use WorkPool.allinstances on many places.

Another case

Instead of

if myLooongexpression.condition then
  myLooongexpression.attributeone
else
  myLooongexpression.attributetwo
endif
 
do this

myLooongexpression->collect(if condition then attributeone else attributetwo endif)

Sunday, November 10, 2013

Bold need your attention

Bold is propably the best persistant framework for Delphi. Only Embarcadero can make it available again. Tell them that community need Bold and give yor votes on QC. Currently it have 216 votes an place 10, but more is needed. Thanks!

Saturday, July 20, 2013

Future for Bold ?

Many may wonder what happened after my petition ? Well, the discussion with Embarcadero is not dead. There are now 176 supporters on the petition and I am still hopeful that we reach a solution for this issue.

Because it is an issue for: 
  1. For those developers that still use Bold in old but important applications. They are forced to stay with an old Delphi version. Many have chosen to leave Delphi for more active development platforms.
  2. For the whole Delphi community that are not aware what a great ORM framework Bold is. For the right type of application ORM and Bold is a really timesaver.
  3. For Embarcadero that miss those Delphi licenses if those customers above would update.
  4. For my employer Attracs as we may need developers with Bold experience. It is not easy to find these days.
I have promised Embarcadero to not reveal any details, but there have been discussions with Embarcadero about how we should continue with Bold. In the meantime I collected some links of Bold resources. Mostly where people mention Bold and what they want it to be. Yes I know I am involved in many discussions... :)

Blogs and forums
Other resources

Friday, November 9, 2012

Use Custom Events to remove dependencies

I have used Delphi a lot but until now not realized how powerful events are. During the last week I got an Aha experience when I realize what can be done. And how clean code can be written with events.

An event is the same a a function pointer for those that use for example C or C++. Delphi have a lot of predefined events. For example a button can have OnClick, OnExit etc. It's easy to use them as Delphi IDE helps you with that.

If you use custom events it can help you break dependencies  between classes. This make it easier to write tests for the code and refactor it.

An Example
This illustrate a form that create and show a dialog. This dialog may also be called from 2 other forms. In the dialog there are special cases to handle this.
First look at the old code before the change:


frmBook.pas
procedure TBookForm.OrderSearch(Sender: TObject);
var
  vForm: TFindParcelForm;
begin
  vForm := TFindParcelForm.Create(self);
  vForm.ShowModal;
end;

procedure TBookForm.OrderNew(Sender: TObject);
begin
  // Code to make new order
end;


frmFindParcel.pas
type  TFindParcelForm = class(TForm)     // Som declarations
end;

// Dependencies to owner
uses
  frmBook,
  frmPlan,
  frmOrg; 

procedure TFindParcelForm.MakeOrderClick(Sender: TObject);
begin
  // Block1 of code here

  if owner is TBookForm) then
    (Owner as TBookForm).OrderNew(self)
  else if Owner is TPlanForm then
    (Owner as TPlanForm).OrderNew(self)
  else if Owner is TOrgForm then
    (Owner as TOrgForm).OrderNew(self)    

  // Block2 of code here
end;

Let's now use the predefined event TNotifyEvent. It is defined in VCL Classes.pas:


TNotifyEvent = procedure(Sender: TObject) of object;

frmBook.pas
procedure TBookForm.OrderSearch(Sender: TObject);
var
  vForm: TFindParcelForm;
begin
  vForm := TFindParcelForm.Create(self);
  vForm.OnNewOrder := OrderNew;
  vForm.ShowModal;
end;

// Have the same signature as TNotifyEvent

procedure TBookForm.OrderNew(Sender: TObject);
begin
  // Code to make new order
end;

frmFindParcel.pas

type  TFindParcelForm = class(TForm)     // Some declarations  private    fNewOrder: TNotifyEvent;  public    property OnNewOrder: TNotifyEvent read fNewOrder write fNewOrder; 
end;

procedure TFindParcelForm.MakeOrderClick(Sender: TObject);
begin
  // Block1 of code here

  if Assigned(OnNewOrder) then
    OnNewOrder(Self);

  // Block2 of code here
end;

So what happened was that we have broken the dependency from FrmFindParcel.pas to the owners TBookForm, TPlanForm and TOrgForm. This means that it is now easier to test frmFindParcel as a separate unit. Method MakeOrderClick is now simplified and is not aware of the owner. If else is also gone.

But we don't need to stop here. With a small addition we can make own custom events as the blog title suggests.

type
  TSetOrder = procedure(aOrder: TOrder; aPrice: Double) of objects;
  TGetOrder = function(): TOrder of objects;

  TFindParcelForm = class(TForm)     // Some declarations  private    fNewOrder: TNotifyEvent;

    fOnSetOrder: TSetOrder;
    fOnGetOrder: TGetOrder;
public    
    property OnNewOrder: TNotifyEvent read fNewOrder write fNewOrder; 
    property OnSetOrder: TSetOrder read fOnSetOrder write fOnSetOrder;
    property OnGetOrder: TGetOrder read fOnGetOrder write fOnGetOrder;
end;

We added 2 new events OnSetOrder that is a procedure with 2 parameters. And OnGetOrder that just return an order.

Usage:

frmBook.pas
procedure TBookForm.OrderSearch(Sender: TObject);
var
  vForm: TFindParcelForm;
begin
  vForm := TFindParcelForm.Create(self);
  vForm.OnNewOrder := OrderNew;
  vForm.OnSetOrder := SetActiveOrder;
  vForm.OnGetOrder := GetActiveOrder;
  vForm.ShowModal;
end;

procedure TBookForm. SetActiveOrder(aOrder: TOrder; aPrice: Double);
begin
  // Code to set Active Order
end;

function TBookForm. GetActiveOrder: TOrder;
begin
  // Code return active Order
end;

// Have the same signature as TNotifyEvent
procedure TBookForm.OrderNew(Sender: TObject);
begin
  // Code to make new order
end;

frmFindParcel.pas


procedure TFindParcelForm.TestOrderClick(Sender: TObject);
var
  vOrder, vOrder2: TOrder;
begin
  // Block1 of code here

  vOrder := MakeOrder;

  if Assigned(OnSetOrder) then
    OnSetOrder(vOrder);

  if Assigned(OnGetOrder) then
    vOrder2 := OnGetOrder;


  // Block2 of code here
end;

So to break dependencies and make code more testable, own custom events are a powerful tool to accomplish that.

Thursday, June 14, 2012

Vote on Bold for Delphi

Hi!

I have voted on this report on Delphi quality central http://qc.embarcadero.com/wc/qcmain.aspx?d=97382. Please do the same to support a change in this issue!

1. Login, if you don't have account create one.
2. Add 5 votes. That is maximum.

PS
Please join then new group on FaceBook
http://www.facebook.com/groups/279755425455148/

My twitter:
https://twitter.com/#!/d98rolb