Programming techniques
The things that matter (and should know)
A well known starting point for every .Net developer.
public class Program
{
public static void int Main(param string[] args)
{
Console.WriteLine("The Moment to Change the World Is Right Now.");
return 0;
}
}
I am not going to tell you witch pattern to use, or that you must do Test Driven Development (TDD) or Behaviour Driven Development (BDD),
- Try a new concept, use a Sanbox project (Experiment first).
- Always start writing code in concept style (interface first.)
Why using a Sandbox project is a good idea
In the past 25 years writing little sanbox applications, most of them were console based, have helpt me a great deal. This is what I like to call the Experiment First Approach This is because they are mostly monolithic, they don't follow any clean code rules or patterns (not perse, though u can train writing them). If you prefer, a Unit Test project can also be used as an experiment first approach. When your done, throw it away or keep it, it will add to your knowlege and private codebase. It will give you practice in specific parts of the programming language and libraries. Or something to look at in simulair cases.
Always start writing in conceptual notation
There is a really intresting thing, or a habbit, I see quite often with many programmers when writing code. They tend to write a class first, a some public members and than extract an Interface from that class with the same name as the implemented class, only prefixed with an 'I'. Often containing many methods that don't add value to the public API of the codebase. Leaving everyone with cluttered interfaces, or whose, having only maker interfaces that are empty interfaces that don't contain any fields or methods in it.
So, the way I like to write, is from a perspective of conceptual notation. (when write a library, Behavioral Unit Tests will guide you to write public API's)
We should start by having an entry point, and write in a way we like to see our end result program to be:
class Program
{
static int Main(string[] args)
{
var number = new Sorted<string>();
if(ArgumentsNotEmpty(args))
{
var filename = arg[1]
if(CanReadFromFile(filename)) {
numbers = ReadNumberFromFile(filename);
}
else
{
Console.Error.WriteLine("File not found: {0}", filename);
return 1;
}
}
else
{
numbers = ReadNumbersFromStdIn();
}
var result = ConvertToOutputFormat(numbers);
Console.WriteLine(result);
return 0;
}
}
We only think and writeout our steps to get the to the result require.
As you can see, there are 5 pieces of the program I didn't write.
- ArgumentsNotEmpty
- CanReadFromFile
- ReadNumberFromFile
- ReadNumbersFromStdIn
- ConvertToOutputFormat
At this moment we can start fill in the 'blanks', and think of how we want to solve these particular problems.
class Program
{
static int Main(string[] args)
{
...
}
/// the array must not be empty
static bool ArgumentsNotEmpty(string[] args)
=> args.Length != 0;
// for now basic check if the file exists
static bool CanReadFromFile(string filename)
=> File.Exists(filename);
// read without checking
static Sorted<string> ReadNumberFromFile(string filename)
=> new SortedSet<string>(File.ReadAllLines(filename));
// take any values line by line
// on the command line we can pipe output from any program as our input
static Sorted<string> ReadNumbersFromStdIn()
{
var number = new Sorted<string>();
string s;
while ((s = Console.ReadLine()) != null)
{
numbers.Add(s);
}
return numbers;
}
// lets build an output of 8 numbers perline in an CSV format
static string ConvertToOutputFormat(ICollection<string> numbers)
=> string.Join("," + Environment.NewLine,
Split(numbers, 8)
.Select(n => string.Join(",", n.Select(v => "\"" + v + "\""))));
// split an array in to groups or chunks
static IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> source, int pos = 3)
=> source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / pos)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}
This is much the same way as writing behavioral tests first. When I start with thinking of purpose and use within the application first. The Unit Tests reprisent our functional design specification. As you know, Functional Design Specification does not contain any highly technical detail. Rather, it describes how the proposed system will operate, how people will interact with it and what to expect when different operational scenarios occur.