Jump to content

Primož Gabrijelčič

Members
  • Content Count

    247
  • Joined

  • Last visited

  • Days Won

    11

Posts posted by Primož Gabrijelčič


  1. While writing Design Patterns with Delphi, I spent quite some time researching existing literature on design patterns implementation in Delphi, design patterns in other languages, other types of patterns, design principles and so on …

     

    In case you would like to dig deeper than the book takes you, here is my reading list.

    Design Patterns Essentials

    Software design pattern

    Computer Science Design Patterns

    The 23 patterns from the GoF

    Design Patterns with examples in different languages (including Delphi)     

    Gang of Four Design Patterns Reference Sheet

    Programming principles

    Design principles and design patterns

    SOLID

    Don't Repeat Yourself (DRY)

    KISS

    YAGNI (You Ain't Gonna Need It)

    Software Design Patterns Are Not Goals, They Are Tools

    I'm Sick Of GoF Design Patterns

    Software Development AntiPatterns

    Big Ball of Mud

    Design Patterns for Humans

    Spring4D
       
    MMX Code Explorer

    Singleton

    https://en.wikipedia.org/wiki/Singleton_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Singleton

    http://www.yanniel.info/2010/10/singleton-pattern-delphi.html

    https://ibeblog.com/2010/08/18/delphi-singleton-patterns/

    https://stackoverflow.com/a/1409672/4997

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Creational.Singleton

    https://stackoverflow.com/questions/1409593/creating-a-singleton-in-delphi-using-the-new-features-of-d2009-and-d2010

    https://sourcemaking.com/design_patterns/singleton

    https://schellingerhout.github.io/design%20patterns/design-patterns-creational-delphi/

    https://github.com/kamranahmedse/design-patterns-for-humans#-singleton

    Dependency injection 

    https://en.wikipedia.org/wiki/Dependency_injection

    http://www.nickhodges.com/post/Service-Locator-is-Indeed-an-Anti-pattern.aspx

    https://softwareengineering.stackexchange.com/questions/135914/why-was-dependency-injection-pattern-not-included-in-the-gang-of-four/135982

    https://stackoverflow.com/questions/4176520/what-is-the-difference-between-strategy-pattern-and-dependency-injection

    Lazy Initialization

    https://en.wikipedia.org/wiki/Lazy_initialization

    Object pool

    https://en.wikipedia.org/wiki/Object_pool_pattern

    https://sourcemaking.com/design_patterns/object_pool

    Factory method

    https://en.wikipedia.org/wiki/Factory_method_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Factory_method    

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Creational.FactoryMethod                     

    https://sourcemaking.com/design_patterns/factory_method

    https://schellingerhout.github.io/design%20patterns/design-patterns-creational-delphi/

    https://github.com/kamranahmedse/design-patterns-for-humans#-factory-method

    Abstract factory

    https://en.wikipedia.org/wiki/Abstract_factory_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Abstract_Factory

    http://www.felix-colibri.com/papers/design_patterns/factory_and_bridge_patterns/factory_and_bridge_patterns.html#abstract_factory_pattern

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Creational.AbstractFactory

    http://www.nickhodges.com/post/Delphi-and-the-Factory-Pattern-Simple-Factory.aspx

    https://sourcemaking.com/design_patterns/abstract_factory

    https://schellingerhout.github.io/design%20patterns/design-patterns-creational-delphi/

    https://github.com/kamranahmedse/design-patterns-for-humans#-abstract-factory

    Prototype

    https://sourcemaking.com/design_patterns/prototype

    https://schellingerhout.github.io/design%20patterns/design-patterns-creational-delphi/

    https://en.wikipedia.org/wiki/Object_copying#Deep_copy

    https://github.com/kamranahmedse/design-patterns-for-humans#-prototype

    Builder

    https://en.wikipedia.org/wiki/Builder_pattern

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Creational.Builder

    https://sourcemaking.com/design_patterns/builder

    https://schellingerhout.github.io/design%20patterns/design-patterns-creational-delphi/

    https://github.com/kamranahmedse/design-patterns-for-humans#-builder

    Composite

    https://en.wikipedia.org/wiki/Composite_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Composite

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Structural.Composite

    https://sourcemaking.com/design_patterns/composite

    https://github.com/kamranahmedse/design-patterns-for-humans#-composite

    Flyweight

    https://en.wikipedia.org/wiki/Flyweight_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Flyweight

    https://sourcemaking.com/design_patterns/flyweight

    https://github.com/kamranahmedse/design-patterns-for-humans#-flyweight

    https://en.wikipedia.org/wiki/String_interning   

    Marker interface

    https://en.wikipedia.org/wiki/Marker_interface_pattern

    Bridge

    https://stackoverflow.com/questions/350404/how-do-the-proxy-decorator-adapter-and-bridge-patterns-differ

    https://en.wikipedia.org/wiki/Bridge_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Bridge

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Structural.Bridge

    https://sourcemaking.com/design_patterns/bridge

    http://www.felix-colibri.com/papers/design_patterns/factory_and_bridge_patterns/factory_and_bridge_patterns.html#the_bridge_design_pattern

    https://simpleprogrammer.com/design-patterns-simplified-the-bridge-pattern/

    https://github.com/kamranahmedse/design-patterns-for-humans#-bridge

    https://stackoverflow.com/q/319728/4997

    Adapter

    https://en.wikipedia.org/wiki/Adapter_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Adapter

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Structural.Adapter      

    https://sourcemaking.com/design_patterns/adapter

    https://github.com/kamranahmedse/design-patterns-for-humans#-adapter

    Proxy

    https://en.wikipedia.org/wiki/Proxy_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Proxy

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Structural.Proxy

    https://sourcemaking.com/design_patterns/proxy

    https://github.com/kamranahmedse/design-patterns-for-humans#-proxy

    Decorator

    https://en.wikipedia.org/wiki/Decorator_pattern

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Structural.Decorator

    https://sourcemaking.com/design_patterns/decorator

    https://github.com/kamranahmedse/design-patterns-for-humans#-decorator

    Facade

    https://en.wikipedia.org/wiki/Facade_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Facade

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Structural.Facade

    https://sourcemaking.com/design_patterns/facade

    https://github.com/kamranahmedse/design-patterns-for-humans#-facade

    Null object

    https://en.wikipedia.org/wiki/Null_object_pattern

    https://sourcemaking.com/design_patterns/null_object

    Template method

    https://en.wikipedia.org/wiki/Template_method_pattern

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Behavioral.TemplateMethod

    https://www.codeproject.com/Articles/516094/TemplateplusMethodplusDesignplusPatternplusinplusD

    https://sourcemaking.com/design_patterns/template_method

    https://github.com/kamranahmedse/design-patterns-for-humans#-template-method

    Command

    https://en.wikipedia.org/wiki/Command_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Command

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Behavioral.Command

    https://sourcemaking.com/design_patterns/command

    https://github.com/kamranahmedse/design-patterns-for-humans#-command

    https://stackoverflow.com/q/6064116/4997

    State

    https://en.wikipedia.org/wiki/State_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/State

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Behavioral.State

    https://sourcemaking.com/design_patterns/state

    https://sourcemaking.com/design_patterns/state/delphi

    https://github.com/kamranahmedse/design-patterns-for-humans#-state

    https://en.wikipedia.org/wiki/Finite-state_machine

    Iterator

    https://en.wikipedia.org/wiki/Iterator_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Iterator

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Behavioral.Iterator

    https://sourcemaking.com/design_patterns/iterator

    https://github.com/kamranahmedse/design-patterns-for-humans#-iterator

    http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Declarations_and_Statements_(Delphi)#For_Statements

    Visitor

    https://en.wikipedia.org/wiki/Visitor_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Visitor

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Behavioral.Visitor

    https://sourcemaking.com/design_patterns/visitor

    https://sourcemaking.com/design_patterns/visitor/delphi     

    https://github.com/kamranahmedse/design-patterns-for-humans#-visitor   

    Observer

    https://en.wikipedia.org/wiki/Observer_pattern

    https://en.wikipedia.org/wiki/Publish–subscribe_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Observer

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Behavioral.Observer

    https://github.com/spinettaro/delphi-event-bus

    https://sourcemaking.com/design_patterns/observer/delphi

    https://github.com/kamranahmedse/design-patterns-for-humans#-observer

    http://docwiki.embarcadero.com/Libraries/en/System.Messaging.TMessageManager

    http://docwiki.embarcadero.com/RADStudio/en/Using_the_RTL_Cross-Platform_Messaging_Solution

    http://docwiki.embarcadero.com/RADStudio/en/Sending_and_Receiving_Messages_Using_the_RTL

    http://docwiki.embarcadero.com/Libraries/en/System.Classes.TComponent.Observers

    Memento

    https://en.wikipedia.org/wiki/Memento_pattern

    https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Memento

    https://github.com/jimmckeeth/DelphiPatterns/tree/master/Behavioral.Memento

    https://sourcemaking.com/design_patterns/memento

    https://github.com/kamranahmedse/design-patterns-for-humans#-memento

    Lock

    https://en.wikipedia.org/wiki/Lock_(computer_science)

    https://en.wikipedia.org/wiki/Spinlock

    Lock striping

    https://netjs.blogspot.si/2016/05/lock-striping-in-java-concurrency.html

    Double-checked locking

    https://en.wikipedia.org/wiki/Double-checked_locking

    https://en.wikipedia.org/wiki/Test_and_test-and-set

    Optimistic locking

    https://www.javaworld.com/article/2075406/java-web-development/optimistic-locking-pattern-for-ejbs.html

    https://martinfowler.com/eaaCatalog/optimisticOfflineLock.html

    https://en.wikipedia.org/wiki/Optimistic_concurrency_control

    Readers-writer lock

    https://en.wikipedia.org/wiki/Readers–writer_lock

    https://docs.microsoft.com/en-us/windows/desktop/sync/slim-reader-writer--srw--locks

    Thread pool

    https://en.wikipedia.org/wiki/Thread_pool

    https://stackoverflow.com/questions/47504201/delphi-ttask-and-tthreadpool

    Messaging

    https://en.wikipedia.org/wiki/Message_passing

    https://en.wikipedia.org/wiki/Message_queue

    Future

    https://en.wikipedia.org/wiki/Futures_and_promises

    Pipeline

    https://en.wikipedia.org/wiki/Staged_event-driven_architecture

    Designing Delphi programs

    https://en.wikipedia.org/wiki/Event-driven_programming

    http://blong.com/Articles/Actions/Actions.htm

    https://github.com/andrea-magni/TFrameStand

    https://martinfowler.com/eaaCatalog/tableModule.html     

    https://stackoverflow.com/questions/433819/table-module-vs-domain-model 

    http://docwiki.embarcadero.com/RADStudio/en/LiveBindings_in_RAD_Studio

    https://www.embarcadero.com/images/dm/technical-papers/understanding_rad_studio_livebindings.pdf

    Other kinds of patterns

    https://en.wikipedia.org/wiki/Exception_handling

    http://wiki.c2.com/?ExceptionPatterns

    http://docwiki.embarcadero.com/Libraries/en/System.TObject.Destroy

    http://www.heaventools.com/eurekalog-exception-logger.htm

    http://www.madshi.net/madExceptDescription.htm

    https://github.com/project-jedi/jvcl

    https://en.wikipedia.org/wiki/Debugging_patterns

    https://git-scm.com/docs/git-bisect

    http://www.washi.cs.waseda.ac.jp/wp-content/uploads/2017/03/Woei-Kae-Chen.pdf

    https://github.com/colinj/Functional

    https://fsharpforfunandprofit.com/fppatterns/

    https://en.wikipedia.org/wiki/Comparison_of_programming_paradigms

    Books & papers

    Architectural Patterns, Pethuru Raj, Anupama Raman, Harihara Subramanian

    Coding in Delphi, Nick Hodges

    Concurrency with Modern C++, Rainer Grimm

    Concurrent Patterns and Best Practices, Atul S. Khot

    Dependency Injection in Delphi, Nick Hodges

    Design Patterns for Humans, Kamran Ahmed

    Design Patterns Past and Future, Aleksandar Bulajic

    Design Patterns - Elements of Reusable Object-Oriented Software, Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

    Dive Into Design Patterns, Alexander Shvets

    Java Design Patterns, Devendra Singh

    More Coding in Delphi, Nick Hodges

    The Null Object Pattern, Bobby Woolf

    • Like 8
    • Thanks 19

  2. FastMM4 works perfectly and has no leaks as far as I know.  We are using FastMM4 in Delphi applications that run 24/7 for years at the time and it works just fine.

     

    That holds for the latest FastMM from https://github.com/pleriche/FastMM4. I have no idea how built-in FastMM works.

     

    One should just be careful when running FastMM4 with /dFullDebugMode. In this mode, FastMM never returns memory to the operating system and your code can run out of memory. This is a feature, not a bug.

    • Thanks 1

  3. 2 hours ago, Roberto Dall'Angelo said:

    Are there basic rules to understand the complexity? Like understand ifis O(n) or O(log n)

     

    If we are talking about time complexity (which is the usual case) and not space complexity, you can think about O() as telling you how slower your code will become if you increase the input size. Very roughly put, O(some_function_of_n) will make the code some_function_of_n slower if you increase the input by a factor of n.

     

    If your code needs M time to process m elements and you now run it on 20*m elements, O(1) will do that in time M, O(n) in time 20*M, O(n^2) in time 400*M, and O(log n) in time 4*M. 


  4. Just for the fun of it, here's a parallel version of FizzBuzz. No RNGs were abused this time.

     

    program ParallelFizzBuzz;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      Winapi.Windows,
      System.SysUtils, System.Classes;
    
    var
      GWrittenOut: TArray<boolean>;
    
    procedure FB(num: integer; output: string; extra: integer);
    begin
      TThread.CreateAnonymousThread(procedure begin
        Sleep(num* 1000 + extra);
        if not GWrittenOut[num] then begin
          Write(output, ' ');
          GWrittenOut[num] := true;
        end;
      end).Start;
    end;
    
    procedure FizzBuzz(upTo: integer);
    var
      i: integer;
    begin
      SetLength(GWrittenOut, upTo+1);
      for:= 1 to upTodo
        FB(i, i.ToString, 900);
      for:= 1 to upTo div 3 do
        FB(i*3, 'Fizz', 500);
      for:= 1 to upTo div 5 do
        FB(i*5, 'Buzz', 500);
      for:= 1 to upTo div 15 do
        FB(i*15, 'FizzBuzz', 100);
    end;
    
    var
      Msg: TMsg;
    
    begin
      FizzBuzz(20);
      while not GWrittenOut[High(GWrittenOut)] do
        while integer(PeekMessage(msg, 0, 0, 0, PM_REMOVE)) <> 0 do begin
          TranslateMessage(Msg);
          DispatchMessage(Msg);
        end;
      Writeln;
      Write('> '); Readln;
    end.

     


  5. Today I learned about pseudo random number generator driven FizzBuzz (https://stackoverflow.com/q/20957693) and I couldn't stop myself from porting it to Delphi ...

    program FizzBuzzRandom;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    procedure FizzBuzz(upTo: integer);
    var
      i: integer;
    begin
      for:= 1 to upTodo begin
        if (i mod 15) = 1 then
          RandSeed := 1973472511;
        Write(TArray<string>.Create(i.ToString, 'Fizz', 'Buzz', 'FizzBuzz')[Random(521) mod 4], ' ');
      end;
    end;
    
    begin
      FizzBuzz(100);
      Readln;
    end.

     

    • Confused 1

  6. Yes, they work 🙂 (and why wouldn't they?). 

     

    program RecursiveAnon;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    function MakeFib: TFunc<integer,int64>;
    var
      fib: TFunc<integer,int64>;
    begin
      fib :=
        function (value: integer): int64
        begin
          if value < 3 then
            Result := 1
          else
            Result := fib(value - 1) + fib(value -2);
        end;
      Result := fib;
    end;
    
    begin
      var fib := MakeFib;
      for var:= 1 to 10 do
        Write(fib(i), ' ');
    
      Readln;
    end.

     

    • Like 2
    • Thanks 1

  7. Indeed, I got the "obvious" part from Hoare 🙂

     

    The parallel part is all mine though. And I stand behind it.

     

    If one writes a unit test which tests the specification in full, it can in theory prove that a single-threaded unit complies with the specification.

     

    Throwing parallel processing in the mix, however, prevents us from even that result. At most one can say is that the unit probably works as expected inside one test environment on one computer.

    • Like 1

  8. 1 hour ago, Rudy Velthuis said:

    Obviously testing thread-related code is hard too. :classic_wink:

    Indeed.

     

    In single-threaded code, good unit tests will show that the code obviously has no errors.

    In multi-threaded code, good unit tests will show that the code has no obvious errors.

     

    IOW, unit tests can only prove that your multi-threaded code doesn't work, not that it does.

    • Like 2

  9. BTW, OmniThreadLibrary's TOmniBoundedQueue was implemented in 2008. Then we needed about a year to find few weird boundary conditions where the code would crash and fix them. 

     

    After that the queue was working perfectly until 2018, when I found a race condition which caused the queue to say "sorry, can't add an item, the queue is full", when the queue has actually just become empty. Nobody noticed the problem in the meantime, we all thought the code is perfect, and the unit/stress test did not test for this specific scenario ...

     

    Writing lock-free structures is harder than you think. (Applies to me, too.)

    • Like 1
    • Thanks 1

  10. The writer also doesn't work.

     

    function TMWSRList.AddItem(pItem : Integer):Integer;
    var
      aOverFlow : Integer;
    begin
      Result := InterlockedIncrement(FWriteIndex);
    
      if Result >= MAX_SIZE then
      begin
        aOverFlow := Result - MAX_SIZE;
    	
        { Reset FWriteIndex when it reaches MAX_SIZE }
        InterlockedCompareExchange(FWriteIndex, -1, MAX_SIZE + aOverFlow);
        Result := InterlockedIncrement(FWriteIndex);
      end;
    
      FItems[Result] := pItem;
      InterlockedIncrement(FAvailableCount);
    
      if Assigned(FOnNewItemAdd) then  
        FOnNewItemAdd(self);
    end;
    1. FWriteIndex is at the end of array.
    2. Two threads call AddItem.
    3. Both threads increment FWriteIndex.
    4. Both threads enter `if`.
    5. Second thread executes InterlockedCompareExchange and InterlockedIncrement. That will skip slot 0 which will never be used, if I'm not mistaken.

    Plus - what use is InterlockedCompareExchange if you never test if the exchange was successful?

     

    Plus - the code doesn't work if the queue overflows (reader stops but writers keep writing). But that is by design, I guess?

     


  11. Definitely doesn't work correctly. For starters, two parallel readers would clash horribly.

     

    If you want to implement lock-free structures, start by writing thorough stress-tests. They should run different scenarios - one reader, few readers, many readers ... very many readers (more than the number of cores in the system) - in a loop which runs for a long time (minutes, at least, preferably more).  

     

    If you want to use something that is well-tested, take TOmniBoundedQueue from the OmniThreadLibrary.

    • Like 1
×