Skip to content

Instantly share code, notes, and snippets.

@ralfw
Last active July 22, 2022 07:14
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ralfw/363cc2a4f4a8dd9e19f28586c8bcd39b to your computer and use it in GitHub Desktop.
Save ralfw/363cc2a4f4a8dd9e19f28586c8bcd39b to your computer and use it in GitHub Desktop.
Layered design vs stratified design
using System;
using System.Linq;
namespace layered
{
class MainClass
{
public static void Main(string[] args) {
var data = new DataLayer();
var business = new BusinessLayer(data);
var presentation = new PresentationLayer(business);
presentation.Show();
}
}
class PresentationLayer {
readonly BusinessLayer business;
public PresentationLayer(BusinessLayer business) {
this.business = business;
}
public void Show() {
Console.Write("Text: ");
var text = Console.ReadLine();
var n = this.business.Count_words(text);
Console.WriteLine($"Number of words: {n}");
}
}
class BusinessLayer {
readonly DataLayer data;
public BusinessLayer(DataLayer data) {
this.data = data;
}
public int Count_words(string text) {
var words = Extract_words(text);
return words.Length;
}
private string[] Extract_words(string text) {
var words = text.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
return Remove_stopwords(words);
}
private string[] Remove_stopwords(string[] words) {
var stopwords = this.data.Load_stopwords();
words = words.Except(stopwords).ToArray();
return words;
}
}
class DataLayer {
public string[] Load_stopwords() {
return System.IO.File.ReadAllLines("stopwords.txt");
}
}
}
using System;
using System.Linq;
namespace stratified
{
class MainClass
{
public static void Main(string[] args) {
var data = new Data();
var business = new Business();
var presentation = new Presentation();
var app = new App(presentation, business, data);
app.Run();
}
}
class App {
readonly Presentation presentation;
readonly Business business;
readonly Data data;
public App(Presentation presentation, Business business, Data data) {
this.presentation = presentation;
this.business = business;
this.data = data;
}
public void Run() {
var text = presentation.Ask_for_text();
var n = Count_words(text);
presentation.Display_word_count(n);
}
private int Count_words(string text) {
var stopwords = data.Load_stopwords();
return Business.Count_words(text, stopwords);
}
}
class Presentation {
public string Ask_for_text() {
Console.Write("Text: ");
return Console.ReadLine();
}
public void Display_word_count(int n) {
Console.WriteLine($"Number of words: {n}");
}
}
class Business {
public static int Count_words(string text, string[] stopwords) {
var words = Extract_words(text);
words = Remove_stopwords(words, stopwords);
return words.Count();
}
private static string[] Extract_words(string text) {
return text.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
}
private static string[] Remove_stopwords(string[] words, string[] stopwords) {
return words.Except(stopwords).ToArray();
}
}
class Data {
public string[] Load_stopwords() {
return System.IO.File.ReadAllLines("stopwords.txt");
}
}
}
@esebastian
Copy link

I've noticed that this.business is not being used in the stratified version of the code, but the static method Business.Count_words is used instead. Is there any specific reason for that?

@ralfw
Copy link
Author

ralfw commented Mar 21, 2021

The reason of this.business not being used is... that I copied the code and forgot to remove it, I guess😉

The use of Business.Count_words as a static method is intentional. It's following the pattern "functional core, imperative shell". The Business class belongs to the core of the application, its domain. Since the domain does not depend on the periphery there is no need for DIP/IoC. Hence a static class for increased testability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment