Coding patterns

From Liberty Eiffel Wiki
Revision as of 13:11, 5 July 2024 by Hzwakenberg (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Coding Patterns are a group of useful insights on how to implement things.

Singleton

To me, the best way to achieve a singleton is almost the standard Eiffel pattern: a singleton holder with a once function, and the pattern itself with a creation clause limited to the singleton holder. An interesting thing is that I usually make the singleton holder expanded, this way I don't have to make it a singleton too ;-)

expanded class SINGLETON_HOLDER
feature {ANY}
   singleton: SINGLETON is
      once
         create Result.make
      end
end
class SINGLETON is
create {SINGLETON_HOLDER}
   make
feature {}
   make is
      do
      end
end

The other solution is the classic holder you either inherit or, preferably, insert.

Which do you prefer: expanded or insert?

Multi-typed

It is becoming quite usual to have a few classes that want to "talk" to "any" class. But you cannot use the ANY class since most classes insert it and anyway it could not hold expanded classes. In that case you use a generic class, which can hold anything that inserts its generic constraint.

An emerging coding pattern is the following:

deferred class TALKABLE
feature {ANY}
   talk is
      do
      end
end
deferred class UNTYPED_TALKER
feature {ANY}
   make_it_talk is
      do
      end
end
class TYPED_TALK[O_->TALKABLE]
inherit
   UNTYPED_TALK

create {ANY}
   set_item

feature {ANY}
   item: O_

   set_item (a_item: like item) is
      require
         a_item /= Void
      do
         item := a_item
      ensure
         item = a_item
      end

   make_it_talk is
      do
         item.talk
      end
end

You can see such a pattern in action in LINKED_LIST where it is used to collect unused cells (look at common_free_nodes which contains ANY_LINKED_LIST_NODE of which LINKED_LIST_NODE is a conformant heir).

Another example is INTERNALS[1].