SlideShare une entreprise Scribd logo
1  sur  2
Télécharger pour lire hors ligne
PROGRAMMER’S WORKSHOP
T
HE PREVIOUS COLUMN1
PROPOSED THAT THE
essence of effective interface design is in
being concise, consistent and conventional.
Not exactly a rule of three that inspires the reader
with its audacity, inspiration and wit, but certainly
a solid foundation for communication rooted in
the principle of least astonishment.
The following Java code expresses an interface
with such aspirations:
interface RecentlyUsedList
{
boolean isEmpty();
int size();
int capacity();
void clear();
void push(String newHead);
String elementAt(int index);
...
}
A recently used list holds a potentially bounded
sequence of unique strings, with the most recently
pushed at the head (the zeroth position), and
such that any overflow of the capacity (where
the size would exceed the upper size bound) loses
the least recently used.
What would this interface look like in C#?
Java and C# are sufficiently similar that in theory
one could define the interface almost identically
in both languages. However, in practice this would
not make the best use of either language’s features
and idioms, and would present any user with
unconventional usage in one language or the
other, or even both.The difference in features, most
notably properties and indexers, would make the
C# interface impossible to implement in Java
and the Java interface an inappropriate pidgin in
C#. The following is a C# interface that strikes a
balance between convention and reason:
interface RecentlyUsedList
{
int Count { get; }
int Capacity { get; }
void Clear();
void Push(string newHead);
string this[int index] { get; }
...
}
A different case convention is used for public
members, and the names follow those typical of
the .NET libraries rather than the Java style, e.g.
Count rather than size. Both Count and Capacity
are expressed as read-only properties (supporting
get only, no set) and subscripted element access is
expressed using an indexer rather than a named
method. Indexers provide interface users with
familiar syntax for working with collections by key
or index, e.g. list[0].
Note that one thing that is missing from the C#
interface, which is found in the Java version, is a
query for emptiness.This query is not offered directly
by .NET collections, so the effect is achieved
the long-handed way: list.Count == 0. Although
technically this is the same, the intention of the
idiom is weaker – compare “my glass is empty” with
“my glass has zero content”. Such an omission is
also a questionable one on technical grounds.
Although an emptiness query must have the
same functional behaviour as comparing the size
against zero, it is not always the case that it
would have the same operational behaviour2
.
From a collection implementer’s perspective, it is
easy to determine whether any collection is empty
in constant time, but it may prove impossible to
determine the size in constant time without
introducing an additional field to track it. The
implementer is forced to adopt a representation
strategy that is sometimes more general than
common usage dictates.
Of course, there is nothing to prevent a
programmer providing an emptiness query; it is
just that it is not the conventional approach.
However, its absence as part of convention does
not mean that there is an absence in the surrounding
idiom that would guide it: IsEmpty, rather than Empty,
would be the name; a property, rather than a
method, would be the means of expression.
The one minor but notable departure from
the convention used in the .NET libraries is the
name of the interface: the version here is named
RecentlyUsedList, not IRecentlyUsedList. Although
a popular convention, dating back to Microsoft’s
early forays into component architectures, the I-
prefix one is a questionable one. As a practice it suffers
40 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.co.uk
Kevlin Henney balances convention and reason when considering interfaces
for similar functionality expressed in different languages.
Conventional & reasonable
MAY–JUNE 2004 41
from inconsistency: classes are not prefixed with C, or delegate types
with D, or enumeration types with E, or struct types with S, nor
should they be – down that path lies the viral Hungarian
Notation meme, where you would start adding prefixes signifying
whether a type is abstract, sealed, public, internal, Pisces,
vegetarian, available on Tuesdays, etc. Such practices are typically
redundant and are often focused on addressing the wrong
development issue: the type system (and therefore the development
environment) already knows what the type is and, in order to use
a type meaningfully, so must the programmer.
Having all the interfaces clustered in one part of the alphabet
is also particularly unhelpful when it comes to alphabetically ordered
listings: it adds little and can hide the presence of other types whose
names legitimately begin with I but are not interfaces, e.g.
IndexOutOfRangeException, Icon and IISIntrinsicsAttribute
(now, just imagine if Microsoft had made that an interface...).
I have also noticed that the I-prefix convention often seems to
encourage poor class naming. There is a temptation to name the
first implementation of an interface as the interface name less the
prefix. For example, under this naming scheme, RecentlyUsedList
would be a concrete class that implemented an IRecentlyUsedList
interface. The implication is that such an interface would have
only one implementation: it would not be an implementation,
it would be the implementation. This often glosses over the
scope for variation that is possible, and makes it harder to
distinguish between variants – if the first implementation of
IRecentlyUsedList was called RecentlyUsedList, what would
the second one be called? RecentlyUsedList2? Don’t go there.
Concrete classes that implement interfaces should be named
after their distinguishing behavioural or representational
characteristic. For example, one implementation of a
RecentlyUsedList interface might be bounded and implemented
in terms of an array and another might be unbounded and
implemented in terms of a linked list. Reasonable names for these
variants would include BoundedRecentlyUsedList and
UnboundedRecentlyUsedList or RecentlyUsedArray and
RecentlyUsedLinkedList.
So, although the I-prefix convention is well meant, it is in the
end misguided. However, it is common and nowhere near as damned
as full Hungarian Notation, so it becomes a judgement call as to
whether to adopt the convention or not. All other things being
equal, it is worth considering not using it. Nevertheless, where
there is a strong culture of using it, adopting it at least has the merit
of consistency – whatever the idiom’s demerits. This is where the
balancing act between convention and reason plays its part.
Either way, it is safe to say that it would be quite unidiomatic to
adopt it in Java.
For objects, as in society, striving for meaningful equality can
be tougher in practice than in principle. What does it mean for
two objects to be considered equal?
For entity objects, the notion is quite simple: identity equality
is the only meaningful criterion.This means that in both Java and
C# the == operator is the right choice for such comparison, and
there is no need to override the corresponding object equality method,
equals and Equals, respectively. Similarly, in C++ entity objects
are typically manipulated by pointer, and pointer equality
corresponds to identity equality.
For value objects, equality is content- rather than identity-based3
.
In Java this means that, unless there is a one-to-one correspondence
between identity and value, the equals method needs to be
overridden to compare the content, which is often, but not
always, a direct == or equals comparison between corresponding
fields in the two objects. Where equals is overridden it is
important for class users to use it rather than the == operator. For
all of its abstractions and safety features, Java faithfully reproduces
and amplifies one of the classic introductory C pitfalls, namely
comparing strings with == rather than strcmp.
Values in C# can be implemented either as class objects,
preferably immutable, or as struct objects. If a value type is
implemented as a struct, the default version of Equals will use
reflection to compare corresponding fields, which is often the
right thing in terms of functionality but not necessarily in
terms of performance, so overriding it manually is still a sensible
option. If a value type is implemented as an immutable class,
and there is no one-to-one correspondence between value and
identity, the Equals method needs to be overridden. C# also supports
the ability to overload the == operator. It is expected that if you
override Equals for a value type, whether struct or class, you
will also overload == for consistency – and if you overload == you
are also required to overload !=. This is not usual for most
reference types, and would be particularly odd for entity types,
but where a value type is being modelled, such as string, this
overloading is more in line with user expectation than the
default, identity-based version.
In C++ only identity comparison, based on pointers, comes for
free. However, in spite of the compiler’s ability to default a
memberwise assignment operator, there is no assumption of
what constitutes correct equality between value objects. So for value
types equality must be provided manually by overloading the ==
and != operators.
OK, so for entities and values the advice seems clear cut:
identity-based versus content-based equality. What about
collections, such as recently used lists? It is here that black and
white turns to grey. There are situations where what is needed is
content-based equality, and situations where what is needed is identity-
based equality. The difference being between “Do the collections
referred to by these two variables contain the same values
(possibly in the same arrangement)?” and “Do these two variables
refer to the same collection?”.
In C++, the idiom for container types is clear-cut because of the
difference in syntax between using a value and a pointer. This
distinction favours overloading the == operator for value-based equality;
identity equality is already available via pointer comparison. The
differences in Java and C# are not quite as clearly defined.
However, the simplest way to cut through the choices without making
things overly general and more complex for the user – Common
Lisp, for example, supports four notions of equality – is to look
at convention: identity- rather than content-based equality is supported
for collection types. In other words, in these languages collections
are not intrinsically considered to be value types, therefore
equality is defaulted. This conclusion certainly simplifies any
implementation of the RecentlyUsedList interface. s
References
1. Kevlin Henney, “Form Follows Function”,
Application Development Advisor, March 2004.
2. Kevlin Henney, “Inside Requirements”,
Application Development Advisor, May 2003.
3. Kevlin Henney, “Objects of Value”,
Application Development Advisor, November 2003.
PROGRAMMER’S WORKSHOP

Contenu connexe

Tendances

Refactoring for Software Design Smells
Refactoring for Software Design SmellsRefactoring for Software Design Smells
Refactoring for Software Design SmellsGanesh Samarthyam
 
Systematic error management - we ported rudder to zio
Systematic error management - we ported rudder to zioSystematic error management - we ported rudder to zio
Systematic error management - we ported rudder to ziofanf42
 
C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...
C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...
C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...Simplilearn
 
Mit4021 c# and .net
Mit4021   c# and .netMit4021   c# and .net
Mit4021 c# and .netsmumbahelp
 
How I Learned To Apply Design Patterns
How I Learned To Apply Design PatternsHow I Learned To Apply Design Patterns
How I Learned To Apply Design PatternsAndy Maleh
 
GOF Design pattern with java
GOF Design pattern with javaGOF Design pattern with java
GOF Design pattern with javaRajiv Gupta
 
Java Design Pattern Interview Questions
Java Design Pattern Interview QuestionsJava Design Pattern Interview Questions
Java Design Pattern Interview Questionsjbashask
 
STATICMOCK : A Mock Object Framework for Compiled Languages
STATICMOCK : A Mock Object Framework for Compiled Languages STATICMOCK : A Mock Object Framework for Compiled Languages
STATICMOCK : A Mock Object Framework for Compiled Languages ijseajournal
 
Design principle vs design patterns
Design principle vs design patternsDesign principle vs design patterns
Design principle vs design patternsPrabhakar Sharma
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1Shahzad
 

Tendances (20)

Exceptional Naming
Exceptional NamingExceptional Naming
Exceptional Naming
 
Refactoring for Software Design Smells
Refactoring for Software Design SmellsRefactoring for Software Design Smells
Refactoring for Software Design Smells
 
What's in a Name?
What's in a Name?What's in a Name?
What's in a Name?
 
Sda 8
Sda   8Sda   8
Sda 8
 
Presentation
PresentationPresentation
Presentation
 
Lecture 18
Lecture 18Lecture 18
Lecture 18
 
Systematic error management - we ported rudder to zio
Systematic error management - we ported rudder to zioSystematic error management - we ported rudder to zio
Systematic error management - we ported rudder to zio
 
Unit 3
Unit 3Unit 3
Unit 3
 
C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...
C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...
C# Interface | Interfaces In C# | C# Interfaces Explained | C# Tutorial For B...
 
Code Smells
Code SmellsCode Smells
Code Smells
 
Mit4021 c# and .net
Mit4021   c# and .netMit4021   c# and .net
Mit4021 c# and .net
 
How I Learned To Apply Design Patterns
How I Learned To Apply Design PatternsHow I Learned To Apply Design Patterns
How I Learned To Apply Design Patterns
 
GOF Design pattern with java
GOF Design pattern with javaGOF Design pattern with java
GOF Design pattern with java
 
Java Design Pattern Interview Questions
Java Design Pattern Interview QuestionsJava Design Pattern Interview Questions
Java Design Pattern Interview Questions
 
Assessing Product Line Derivation Operators Applied to Java Source Code: An E...
Assessing Product Line Derivation Operators Applied to Java Source Code: An E...Assessing Product Line Derivation Operators Applied to Java Source Code: An E...
Assessing Product Line Derivation Operators Applied to Java Source Code: An E...
 
Gof design patterns
Gof design patternsGof design patterns
Gof design patterns
 
STATICMOCK : A Mock Object Framework for Compiled Languages
STATICMOCK : A Mock Object Framework for Compiled Languages STATICMOCK : A Mock Object Framework for Compiled Languages
STATICMOCK : A Mock Object Framework for Compiled Languages
 
Design principle vs design patterns
Design principle vs design patternsDesign principle vs design patterns
Design principle vs design patterns
 
GRASP
GRASPGRASP
GRASP
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1
 

En vedette

A little motivation
A little motivationA little motivation
A little motivationiverson333
 
Knime customer intelligence on social media odsc london
Knime customer intelligence on social media odsc london   Knime customer intelligence on social media odsc london
Knime customer intelligence on social media odsc london Jessica Willis
 
Linklaters Conference
Linklaters ConferenceLinklaters Conference
Linklaters ConferenceBrand Acumen
 
Punjabi culture
Punjabi culturePunjabi culture
Punjabi cultureBusines
 
Tanzanian innovation on water-filtration system
Tanzanian innovation on water-filtration systemTanzanian innovation on water-filtration system
Tanzanian innovation on water-filtration systemFrancois Stepman
 
IV memorial Cara Campoamor 4.1
IV memorial Cara Campoamor 4.1IV memorial Cara Campoamor 4.1
IV memorial Cara Campoamor 4.1victoriacrespog
 
Establishing HR Consulting Firm in Bangladesh
Establishing HR Consulting Firm in BangladeshEstablishing HR Consulting Firm in Bangladesh
Establishing HR Consulting Firm in BangladeshAbu Jubaer
 
Using Healthcare Data for Research @ The Hyve - Campus Party 2016
Using Healthcare Data for Research @ The Hyve - Campus Party 2016Using Healthcare Data for Research @ The Hyve - Campus Party 2016
Using Healthcare Data for Research @ The Hyve - Campus Party 2016Kees van Bochove
 
Capstream x pr for startups
Capstream x pr for startupsCapstream x pr for startups
Capstream x pr for startupsCapstreamX
 

En vedette (12)

A little motivation
A little motivationA little motivation
A little motivation
 
Knime customer intelligence on social media odsc london
Knime customer intelligence on social media odsc london   Knime customer intelligence on social media odsc london
Knime customer intelligence on social media odsc london
 
Unlocking Blockchain’s Potential
Unlocking Blockchain’s PotentialUnlocking Blockchain’s Potential
Unlocking Blockchain’s Potential
 
Web Landing Pagev211
Web Landing Pagev211Web Landing Pagev211
Web Landing Pagev211
 
Skoda Exp Certificate
Skoda Exp CertificateSkoda Exp Certificate
Skoda Exp Certificate
 
Linklaters Conference
Linklaters ConferenceLinklaters Conference
Linklaters Conference
 
Punjabi culture
Punjabi culturePunjabi culture
Punjabi culture
 
Tanzanian innovation on water-filtration system
Tanzanian innovation on water-filtration systemTanzanian innovation on water-filtration system
Tanzanian innovation on water-filtration system
 
IV memorial Cara Campoamor 4.1
IV memorial Cara Campoamor 4.1IV memorial Cara Campoamor 4.1
IV memorial Cara Campoamor 4.1
 
Establishing HR Consulting Firm in Bangladesh
Establishing HR Consulting Firm in BangladeshEstablishing HR Consulting Firm in Bangladesh
Establishing HR Consulting Firm in Bangladesh
 
Using Healthcare Data for Research @ The Hyve - Campus Party 2016
Using Healthcare Data for Research @ The Hyve - Campus Party 2016Using Healthcare Data for Research @ The Hyve - Campus Party 2016
Using Healthcare Data for Research @ The Hyve - Campus Party 2016
 
Capstream x pr for startups
Capstream x pr for startupsCapstream x pr for startups
Capstream x pr for startups
 

Similaire à Conventional and Reasonable (20)

Substitutability
SubstitutabilitySubstitutability
Substitutability
 
Java mcq
Java mcqJava mcq
Java mcq
 
Advance oops concepts
Advance oops conceptsAdvance oops concepts
Advance oops concepts
 
C# interview
C# interviewC# interview
C# interview
 
The Uniform Access Principle
The Uniform Access PrincipleThe Uniform Access Principle
The Uniform Access Principle
 
Value Added
Value AddedValue Added
Value Added
 
Unequal Equivalence
Unequal EquivalenceUnequal Equivalence
Unequal Equivalence
 
Unit 1 Java
Unit 1 JavaUnit 1 Java
Unit 1 Java
 
Java_Interview Qns
Java_Interview QnsJava_Interview Qns
Java_Interview Qns
 
Tcs NQTExam technical questions
Tcs NQTExam technical questionsTcs NQTExam technical questions
Tcs NQTExam technical questions
 
Oop
OopOop
Oop
 
C# concepts
C# conceptsC# concepts
C# concepts
 
Oop basic concepts
Oop basic conceptsOop basic concepts
Oop basic concepts
 
Evolve Your Code
Evolve Your CodeEvolve Your Code
Evolve Your Code
 
C# program structure
C# program structureC# program structure
C# program structure
 
Technical_Interview_Questions.pdf
Technical_Interview_Questions.pdfTechnical_Interview_Questions.pdf
Technical_Interview_Questions.pdf
 
Introduction to es6
Introduction to es6Introduction to es6
Introduction to es6
 
Core_Java_Interview.pdf
Core_Java_Interview.pdfCore_Java_Interview.pdf
Core_Java_Interview.pdf
 
01. design pattern
01. design pattern01. design pattern
01. design pattern
 
C++ interview question
C++ interview questionC++ interview question
C++ interview question
 

Plus de Kevlin Henney

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical ExcellenceKevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical DevelopmentKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid DeconstructionKevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test CasesKevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to ImmutabilityKevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-InKevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good NameKevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantKevlin Henney
 

Plus de Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 

Dernier

Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 

Dernier (20)

Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 

Conventional and Reasonable

  • 1. PROGRAMMER’S WORKSHOP T HE PREVIOUS COLUMN1 PROPOSED THAT THE essence of effective interface design is in being concise, consistent and conventional. Not exactly a rule of three that inspires the reader with its audacity, inspiration and wit, but certainly a solid foundation for communication rooted in the principle of least astonishment. The following Java code expresses an interface with such aspirations: interface RecentlyUsedList { boolean isEmpty(); int size(); int capacity(); void clear(); void push(String newHead); String elementAt(int index); ... } A recently used list holds a potentially bounded sequence of unique strings, with the most recently pushed at the head (the zeroth position), and such that any overflow of the capacity (where the size would exceed the upper size bound) loses the least recently used. What would this interface look like in C#? Java and C# are sufficiently similar that in theory one could define the interface almost identically in both languages. However, in practice this would not make the best use of either language’s features and idioms, and would present any user with unconventional usage in one language or the other, or even both.The difference in features, most notably properties and indexers, would make the C# interface impossible to implement in Java and the Java interface an inappropriate pidgin in C#. The following is a C# interface that strikes a balance between convention and reason: interface RecentlyUsedList { int Count { get; } int Capacity { get; } void Clear(); void Push(string newHead); string this[int index] { get; } ... } A different case convention is used for public members, and the names follow those typical of the .NET libraries rather than the Java style, e.g. Count rather than size. Both Count and Capacity are expressed as read-only properties (supporting get only, no set) and subscripted element access is expressed using an indexer rather than a named method. Indexers provide interface users with familiar syntax for working with collections by key or index, e.g. list[0]. Note that one thing that is missing from the C# interface, which is found in the Java version, is a query for emptiness.This query is not offered directly by .NET collections, so the effect is achieved the long-handed way: list.Count == 0. Although technically this is the same, the intention of the idiom is weaker – compare “my glass is empty” with “my glass has zero content”. Such an omission is also a questionable one on technical grounds. Although an emptiness query must have the same functional behaviour as comparing the size against zero, it is not always the case that it would have the same operational behaviour2 . From a collection implementer’s perspective, it is easy to determine whether any collection is empty in constant time, but it may prove impossible to determine the size in constant time without introducing an additional field to track it. The implementer is forced to adopt a representation strategy that is sometimes more general than common usage dictates. Of course, there is nothing to prevent a programmer providing an emptiness query; it is just that it is not the conventional approach. However, its absence as part of convention does not mean that there is an absence in the surrounding idiom that would guide it: IsEmpty, rather than Empty, would be the name; a property, rather than a method, would be the means of expression. The one minor but notable departure from the convention used in the .NET libraries is the name of the interface: the version here is named RecentlyUsedList, not IRecentlyUsedList. Although a popular convention, dating back to Microsoft’s early forays into component architectures, the I- prefix one is a questionable one. As a practice it suffers 40 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.co.uk Kevlin Henney balances convention and reason when considering interfaces for similar functionality expressed in different languages. Conventional & reasonable
  • 2. MAY–JUNE 2004 41 from inconsistency: classes are not prefixed with C, or delegate types with D, or enumeration types with E, or struct types with S, nor should they be – down that path lies the viral Hungarian Notation meme, where you would start adding prefixes signifying whether a type is abstract, sealed, public, internal, Pisces, vegetarian, available on Tuesdays, etc. Such practices are typically redundant and are often focused on addressing the wrong development issue: the type system (and therefore the development environment) already knows what the type is and, in order to use a type meaningfully, so must the programmer. Having all the interfaces clustered in one part of the alphabet is also particularly unhelpful when it comes to alphabetically ordered listings: it adds little and can hide the presence of other types whose names legitimately begin with I but are not interfaces, e.g. IndexOutOfRangeException, Icon and IISIntrinsicsAttribute (now, just imagine if Microsoft had made that an interface...). I have also noticed that the I-prefix convention often seems to encourage poor class naming. There is a temptation to name the first implementation of an interface as the interface name less the prefix. For example, under this naming scheme, RecentlyUsedList would be a concrete class that implemented an IRecentlyUsedList interface. The implication is that such an interface would have only one implementation: it would not be an implementation, it would be the implementation. This often glosses over the scope for variation that is possible, and makes it harder to distinguish between variants – if the first implementation of IRecentlyUsedList was called RecentlyUsedList, what would the second one be called? RecentlyUsedList2? Don’t go there. Concrete classes that implement interfaces should be named after their distinguishing behavioural or representational characteristic. For example, one implementation of a RecentlyUsedList interface might be bounded and implemented in terms of an array and another might be unbounded and implemented in terms of a linked list. Reasonable names for these variants would include BoundedRecentlyUsedList and UnboundedRecentlyUsedList or RecentlyUsedArray and RecentlyUsedLinkedList. So, although the I-prefix convention is well meant, it is in the end misguided. However, it is common and nowhere near as damned as full Hungarian Notation, so it becomes a judgement call as to whether to adopt the convention or not. All other things being equal, it is worth considering not using it. Nevertheless, where there is a strong culture of using it, adopting it at least has the merit of consistency – whatever the idiom’s demerits. This is where the balancing act between convention and reason plays its part. Either way, it is safe to say that it would be quite unidiomatic to adopt it in Java. For objects, as in society, striving for meaningful equality can be tougher in practice than in principle. What does it mean for two objects to be considered equal? For entity objects, the notion is quite simple: identity equality is the only meaningful criterion.This means that in both Java and C# the == operator is the right choice for such comparison, and there is no need to override the corresponding object equality method, equals and Equals, respectively. Similarly, in C++ entity objects are typically manipulated by pointer, and pointer equality corresponds to identity equality. For value objects, equality is content- rather than identity-based3 . In Java this means that, unless there is a one-to-one correspondence between identity and value, the equals method needs to be overridden to compare the content, which is often, but not always, a direct == or equals comparison between corresponding fields in the two objects. Where equals is overridden it is important for class users to use it rather than the == operator. For all of its abstractions and safety features, Java faithfully reproduces and amplifies one of the classic introductory C pitfalls, namely comparing strings with == rather than strcmp. Values in C# can be implemented either as class objects, preferably immutable, or as struct objects. If a value type is implemented as a struct, the default version of Equals will use reflection to compare corresponding fields, which is often the right thing in terms of functionality but not necessarily in terms of performance, so overriding it manually is still a sensible option. If a value type is implemented as an immutable class, and there is no one-to-one correspondence between value and identity, the Equals method needs to be overridden. C# also supports the ability to overload the == operator. It is expected that if you override Equals for a value type, whether struct or class, you will also overload == for consistency – and if you overload == you are also required to overload !=. This is not usual for most reference types, and would be particularly odd for entity types, but where a value type is being modelled, such as string, this overloading is more in line with user expectation than the default, identity-based version. In C++ only identity comparison, based on pointers, comes for free. However, in spite of the compiler’s ability to default a memberwise assignment operator, there is no assumption of what constitutes correct equality between value objects. So for value types equality must be provided manually by overloading the == and != operators. OK, so for entities and values the advice seems clear cut: identity-based versus content-based equality. What about collections, such as recently used lists? It is here that black and white turns to grey. There are situations where what is needed is content-based equality, and situations where what is needed is identity- based equality. The difference being between “Do the collections referred to by these two variables contain the same values (possibly in the same arrangement)?” and “Do these two variables refer to the same collection?”. In C++, the idiom for container types is clear-cut because of the difference in syntax between using a value and a pointer. This distinction favours overloading the == operator for value-based equality; identity equality is already available via pointer comparison. The differences in Java and C# are not quite as clearly defined. However, the simplest way to cut through the choices without making things overly general and more complex for the user – Common Lisp, for example, supports four notions of equality – is to look at convention: identity- rather than content-based equality is supported for collection types. In other words, in these languages collections are not intrinsically considered to be value types, therefore equality is defaulted. This conclusion certainly simplifies any implementation of the RecentlyUsedList interface. s References 1. Kevlin Henney, “Form Follows Function”, Application Development Advisor, March 2004. 2. Kevlin Henney, “Inside Requirements”, Application Development Advisor, May 2003. 3. Kevlin Henney, “Objects of Value”, Application Development Advisor, November 2003. PROGRAMMER’S WORKSHOP