| Domain concern | Architecture characteristics |
|---|---|
| Mergers and acuisitions | Interoperability, scalability, adaptabilitym, extensibility |
| Time to market | Agility, testability, deployability |
| User satisfaction | Performance, availability, fault tolerance, testability, deployability, agility, security |
| Competitive advantage | Agility, testability, deployability, scalability, availability, fault tolerance |
| Time and budget | Simplicity, feasibility |
Monday, May 29, 2023
Translations of domain concerns architecture characteristics
Tuesday, February 21, 2023
How to detect changes by using Git
In various scenarios, you need to know what files were modified by a developer in your feature or main branch. Knowing which files were modified, you can determine which modules were impacted.
For example, you have a test suite that can take hours to run, and now you are running it in your deployment pipeline on each file change. The benefit of such an approach is that you can guarantee the quality of your product and ensure that your code change doesn't break existing functionality. Still, it hurts your productivity and the possibility of delivering new features quickly.
A solution for this problem could be to run only tests associated with a specific module. Git can help here. You can use the git diff command to get changes.
The first command will produce a diff between two commits:
git diff --name-only <commit>..<commit>
The second command will find diff from their common ancestor.
git diff --name-only <commit>...<commit>
New Version
If you want to get files modified in a new version, run this command:
git diff --name-only v1.0.0..HEAD
The result should look like this:
readme.md src/package1/config.json src/package2/config.json
Feature branch
If you want to get files modified in a branch feature, run this command:
git diff --name-only master...HEAD
The result should look like this:
src/package3/config.json
References
Tuesday, September 13, 2022
Microservice
Microservices are an approach to distributed systems that promote the use of finely grained services that can be changed, deployed, and released independently.
Key Concepts of Microservices
Independent Deployability
Independent deployability is the idea that we can make a change to a microservice, deploy it, and release that change to our users, without having to deploy any other microservices. To ensure independent deployability, we need to make sure our microservices are loosely coupled: we must be able to change one service without having to change anything else. This means we need explicit, well-defined, and stable contracts between services.
Modeled Around a Business DomainBy modeling services around business domains, we can make it easier to roll out new functionality and to recombine microservices in different ways to deliver new functionality to our users.
Owning Their Own StateThis gives the microservices the ability to decide what is shared and what is hidden, which allows us to clearly separate functionality that can change freely (our internal implementation) from the functionality that we want to change infrequently (the external contract that the consumers use).
Microservices embrace the concept of information hiding.1 Information hiding means hiding as much information as possible inside a component and exposing as little as possible via external interfaces.
Monday, August 22, 2022
Architecture
A layered architecture is used to build applications based on domain-driven design. It consists of three main layers:
- Domain
- Application
- Infrastructure
Domain Layer
Infrastructure
Sunday, August 21, 2022
Domain Service
Domain service is used to encapsulate business logic, which could not sit comfortably within an entity or aggregate in the system. Usually, a domain service is created then multiple entities are involved and behavior can't be owned by a single entity.
Characteristics
- Represent behavior
- Stateless
- No identity
public class PricingService : DomainService, IPricingService
{
public Money CalculateTotalPriceFor(IList<item> items, Coupon coupon)
{
// ...
}
}Application Service
public interface ProfileService : ApplicationService, IProfileService
{
public Task<Profile> CreateProfileAsync(string username)
{
// ...
}
public Task<Profile?> GetProfileAsync(int id, CancellationToken cancellationToken)
{
// ...
}
}Infrastructure Service
public class MailService : InfrastructureService, IMailService
{
public virtual async Task SendMailAsync(MailMessage mailMessage)
{
// ...
}
}Wednesday, August 3, 2022
Value Object
One of the domain modeling building blocks is a value object. Value objects are an entity's state, describing something about the entity or the things it owns.
Value objects are always preferred over entities because they are immutable and lightweight. Due this reason, it is easy to work with them.
In the .NET world, records are good candidates to implement value objects. Below, you can see how a value object can look implemented in C#.
public record Money
{
public decimal Amount { get; init; }
public Money(decimal amount)
{
if (amount % 0.01m != 0)
{
throw new ArgumentException("More than two decimal places", nameof(amount));
}
Amount = amount;
}
public Money Add(Money value)
{
return new Money(Amount + value.Amount);
}
public Money Substract(Money value)
{
return new Money(Amount - value.Amount);
}
}Characteristics
Every value object has to match such characteristics:
- Identity-Less
- Attribute-Based Equality
- Immutable
- Behavior-Rich
- Self-Validating
Now let's dive deep into each value objects characteristics.
Identity-Less
Value objects have no identity.
Attribute-Based Equality
Value objects are considered equal if they have the same value.
var a = new Money(10M); var b = new Money(10M);
Console.WriteLine(a == b); // True
Immutable
Once created, a value object can not be changed.
var a = new Money(10M);
a.Amount = 12M; // Can't be assigned
Behavior‐Rich
As much as possible, value objects should expose expressive domain‐oriented behavior and encapsulate the state.
var a = new Money(10M); var b = a.Substract(new Money(2M));
Console.WriteLine(b); // Money { Amount = 8 }Self‐Validating
Value objects should never be in an invalid state.
var a = new Money(10.0348M); // Throws exception "More than two decimal places"
Sunday, May 10, 2015
Dependency Injection in JavaScript
Before answering the question, lets figure out what is dependency injection and what are advantages and disadvantages of it.
Dependency injection is a software design pattern that allows to remove hard-coded dependencies and makes it possible to change them. Dependencies can be injected to the object via the constructor or via defined method or a setter property.
Advantages:
- Dependency Injection decreases coupling between an object and its dependency
- Dependency injection doesn't require any change in code behaviour, it can be applied an existing code
- Dependency injection helps isolate the client from the impact of design changes and defects
- Dependency injection allows the system to be reconfigured without changing the existing code
- Dependency injection allows concurrent or independent development
- Dependency injection allows to make code more maintainable and testable, because dependencies’ impact can be removed by replacing dependencies with mocks or stubs
- When instantiating type you have to know which dependencies to use
- Hides type’s instantiation and dependency resolving logic and if error happens, it can be much harder to figure out what's wrong
- It can require to write more lines of codes
- It can be slower when instantiating a type with keyword new, it’s related to meta data which has to be used while resolving instance
Let’s write some code which implements defined class diagram above.
function Engine() {
this.hp = 256;
}
Engine.prototype.start = function () {
console.log("Engine with " + this.hp + " hp has been started...");
}
function Car() {
this.name = "wv";
this.engine = new Engine();
}
Car.prototype.start = function () {
if (this.engine) {
this.engine.start();
}
}
function Driver() {
this.name = "tom";
this.car = new Car();
}
Driver.prototype.drive = function () {
if (this.car) {
this.car.start();
}
}
var driver = Driver();
driver.drive();
// Engine with 256 hp has been started...
From the first view everything looks OK. This code works. If you don’t need to test it or to change it in the future, this is code is fine. However, this code has some issues, one of which is that dependencies are hard-coded.
function Engine(hp) {
this.hp = hp;
}
Engine.prototype.start = function () {
console.log("Engine with " + this.hp + " hp has been started...");
}
function Car(name, engine) {
this.name = name;
this.engine = engine;
}
Car.prototype.start = function () {
if (this.engine) {
this.engine.start();
}
}
function Driver(name, car) {
this.name = name;
this.car = car;
}
Driver.prototype.drive = function () {
if (this.car) {
this.car.start();
}
}
var driver = Driver("tom");
driver.car = new Car("wv", new Engine(256)));
driver.drive();
// Engine with 256 hp has been started...
We have modified our existing code and it is extensible, but driver’s creation procedure has become more complex. In this case dependency injection container can help us. You can define driver’s details in configuration and when you want to instantiate driver you have to do it using dependency injection resolver. In the example below di4js library is used.
di
.register('engine')
.as(Engine)
.withConstructor()
.param().val(256)
.register('car')
.as(Car)
.withConstructor()
.param().val('wv')
.param().ref('engine')
.register('driver')
.as(Driver)
.withConstructor()
.param().val('tom')
.param().ref('car');
var driver = di.resolve('driver');
driver.drive(); // Engine with 256 hp has been started…
As I mentioned before, that dependency injection may required to write more code as we can see in this example, on the other hand, there is one advantage that configuration is defined in a single place and it can reconfigured without changing the existing code base.
Autowire
If you do not want to define all dependencies manually, there is a solution. You can enable autowired option. If it is enabled for dependency resolver, all type's or instance's dependencies are resolved automatically by names. It may reduce the amount of code necessary to register types and their dependencies. With autowired option enabled you have to register only types. By default autowired is disabled.
Let’s simplify the example in order to show how autowired option works.
function Engine() {
}
Engine.prototype.start = function () {
console.log("Engine has been started...");
}
function Car() {
this.engine = null;
}
Car.prototype.start = function () {
if (this.engine) {
this.engine.start();
}
console.log("Car has been started...");
}
di
.autowired(true)
.register('engine')
.as(Engine)
.register('car')
.as(Car);
var car = di.resolve('car');
car.start();
We are going to see such output in console.
"Engine has been started..." "Car has been started..."
One more and the most common scenario is mixed mode. By default you can allow to resolve dependencies automatically but some dependencies can be defined manually. Manually defined dependency has bigger priority.
If you are using different naming convention from the one given in the example it can be overridden easily. For more details read di4js documentation.
List of Dependencies
In some situations you may need to resolve a list of dependencies. To achieve this you have to make multiple registrations for single name.
Let’s modify our previous example and let’s say that driver can own more than one car at the same time which one to drive. Modified class diagram can be found below.
First of all we need to modify driver’s definition. Property ‘car’ has to be renamed to ‘cars’ and additional parameter ‘name’ has to be added to method ‘drive’. Let’s look to our modified source code.
function Driver(name) {
this.name = name;
}
Driver.prototype.drive = function (name) {
if (this.cars && name) {
if (this.cars instanceof Array) {
for (var i = 0; i < this.cars.length; i++) {
if (this.cars[i].name === name) {
this.cars[i].start();
break;
}
}
} else if (this.cars.name === name) {
this.cars.start();
}
}
}
It’s time to register driver’s dependencies and try to resolve it.
di
.register('engine')
.as(Engine)
.withConstructor()
.param().val(256)
.register('car')
.as(Car)
.withConstructor()
.param().val('wv')
.param().ref('engine')
.register('car')
.as(Car)
.withConstructor()
.param().val('ford')
.param().ref('engine')
.register('tom')
.as(Driver)
.withConstructor()
.param().val('tom')
.withProperties()
.prop("cars").ref('car');
To instantiate driver by name we need to write a single code line.
var tom = di.resolve('tom');
If we invoke method ‘drive’, we will get results which will be printed to console output.
tom.drive('wv');
// Engine with 256 hp has been started…
// Car 'wv' has been started...
Using setter methods instead of properties / fluent interface
There is one more fancy feature. Some objects do not have properties, they have only setter methods and fluent interface. Such scenario with di4js library can be handled too. There is one limitation that these dependencies can not be resolved automatically.
Let’s modify our previous example and replace properties with setter methods.
New defined methods look like this.
Car.prototype.setEngine = function (engine) {
this.engine = engine;
return this;
};
Driver.prototype.setCars = function (cars) {
this.cars = cars;
return this;
};
Below you can see how modified type and its dependencies registration look.
di
.register('engine')
.as(Engine)
.withConstructor()
.param().val(256)
.register('car')
.as(Car)
.withConstructor()
.param().val('wv')
.withProperties()
.func('setEngine')
.param().ref('engine')
.register('car')
.as(Car)
.withConstructor()
.param().val('ford')
.withProperties()
.func('setEngine')
.param().ref('engine')
.register('tom')
.as(Driver)
.withConstructor()
.param().val('tom')
.withProperties()
.func('setCars')
.param().ref('car');
If we resolve driver and invoke its method ‘drive’, we will get the same result as in previous examples.
Child container
In all examples global dependency resolver is used, it’s good for demo purposes and small apps. For bigger apps child dependency resolvers should be created per scope. It allows to get better flexibility and extensibility. Parent can be extended or overridden by child without making an impact on it.
First of all let’s register type in global dependency resolver and then try to resolve registered type by name.
var DieselEngine = function () {
};
DieselEngine.prototype.start = function () {
console.log("Diesel engine has been started...");
};
function Car(engine) {
this.engine = engine;
}
Car.prototype.start = function () {
if (this.engine) {
this.engine.start();
}
console.log("Car has been started...");
}
di
.autowired(true)
.register('engine')
.as(DieselEngine)
.register('car')
.as(Car);
var car = di.resolve('car');
car.start();
We are getting such results.
"Diesel engine has been started..." "Car has been started..."
Now we can create a child container from the parent and then try to resolve overridden type.
var PetrolEngine = function () {
};
PetrolEngine.prototype.start = function () {
console.log("Petrol engine has been started...");
};
var child = di
.create()
.register('engine')
.as(PetrolEngine);
car = child.resolve('car');
car.start();
Now we are getting different results.
"Petrol engine has been started..." "Car has been started..."
Injection to function or object
There is a situation when instance creation can’t be controlled by dependency injection resolver. This situation may occur when you are adapting dependency injection for legacy code or instances are created by other components which you do not control. There is an option to inject dependencies to object or to function.
The first example demonstrates how dependencies can be injected to the function using parameters’ names.
di.inject(function (car) {
car.start();
});
In the second example an array notation is used to inject dependencies to the function.
di.inject(['car', function (car) {
car.start();
}]);
In the following examples I have demonstrated how to inject dependencies to the function. In following examples I am going to demonstrate how dependencies can be injected to an object.
var car = new Car(); di.inject(car); car.start();
There is the second method how to inject dependencies to object. You have to provide registration name which has to be used while injecting dependencies.
var car = new Car(); di.inject(car, 'car'); car.start();
AMD
di4js is compatible with asynchronous module definition (AMD) and it can be loaded as ordinal module.
define(['di4js'], function (di) {
function Engine(hp) {
this.hp = hp;
}
Engine.prototype.start = function () {
console.log("Engine with " + this.hp + " hp has been started...");
}
di
.register("engine")
.as(Engine)
.withConstructor()
.param().val(256);
var engine = di.resolve("engine");
engine.start();
});
Testing
As I mentioned before, if you are using dependency injection your code is maintainable and testable, because dependencies can be replaced with stubs or mocks easily.
In the following example I am going to use a well known testing framework Jasmine. I am going to demonstrate how we can test single method replacing dependencies with mocks.
describe("car", function() {
it("should start a car", function() {
var engineMock = jasmine.createSpyObj('engine', ['start']);
var car = new Car(engineMock);
car.start();
expect(engineMock.start).toHaveBeenCalled();
});
});
As we can see in the example such code can be tested easily.
Why di4js?
di4js is lightweight library which is inspired by Unity, Spring, AngularJS and others. di4js advantages are that it is a small library and it’s dedicated to solve a certain problem, thus it’s not a massive framework which tries to cover everything. It also doesn’t depend on other libraries, so it’s easy to embed it to an existing code base.
You may ask why it was created. The answer is simple. A range of libraries have been investigated and none of them satisfied expectations. The goal was to gather various components from various libraries to a single place. Initially it was written for internal purpose but now a decision has been made to share it. Maybe it will be useful for others too.
di4js can be used in projects which are not build on big frameworks such as AngularJS, because big frameworks have built in solution for dependency management. di4js can be useful when you depend on small dedicated libraries.
Usage
di4js library is released under MIT license. It can be used in modern browsers or in other JavaScript runtimes such as Node.js. Library can be installed from various package managers: nuget, npm or Bower.
To install di4js module for Node.js, this command should be used:
npm install di4js
To install di4js for web browser, run the following command:
bower install di4js
In Visual Studio di4js module can be installed using NuGet extension. To install di4js, run the following command in the package manager console.
Install-Package di4js
If you want to look at the source code or to get more information about library or its usage, just vist https://github.com/gedbac/di4js.
Final thoughts
At the beginning we asked a question “Can dependency injection pattern be used in JavaScript?”. Now we can answer to that question and say that dependency injection can be easily used and is useful in JavaScript, but project size and complexity always has to be considered. Thus, problem has to be identified and after that corresponding solution has to be chosen. Consequently, we can say that every pattern which is used in other languages can be easily adapted to the JavaScript.
Saturday, June 8, 2013
How to define a class in JavaScript?
Introduction
JavaScript is a very flexible programming language. It can be easily extended with new features which are used in other programming languages.
As it was mentioned before, JavaScript is a prototype based scripting language. A prototype is an object and every created function automatically gets a prototype property that points to a new blank object. In earlier versions of JavaScript created objects were vulnerable, because they could be modified at any time accidentally or on purpose. In some cases it’s an advantage, but when it comes to writing libraries it is a hude disadvantage.
Situation changed when ECMAScript 5 version was released. It included many cool features, which allow to have flexibilty and create more reliable and steady libraries. It allows to implement open/close principle: “A module should be open for extension but closed for modifications”. It means that if client programmer wants to extend an existing object he must create his own derived object.
How to define a class in JavaScript?
‘use strict’; // You codes goes here...
var Shape = function () {
this.__x = 0;
this.__y = 0;
};
Shape.prototype = Object.create(Object.prototype, {
x: {
get: function () {
return this.__x;
},
set: function (value) {
this.__x = value;
},
enumerable: true,
configurable: false
},
y: {
get: function () {
return this.__y;
},
set: function (value) {
this.__y = value;
},
enumerable: true,
configurable: false
},
moveTo: {
value: function (x, y) {
this.x = x;
this.y = y;
},
writable: false,
enumerable: true,
configurable: false
},
draw: {
value: function () {
console.log("Drawing shape at: (" + this.x + ", " + this.y + ")");
},
writable: false,
enumerable: true,
configurable: false
}
});
- writable - true if and only if the value associated with the property may be changed with an assignment operator
- enumerable - true if and only if this property shows up during enumeration of the properties on the corresponding object
- configurable - true if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object
Object.seal(Shape); Object.seal(Shape.prototype);
Object.defineProperty(obj, "prop", { value: 17 });
// throws an error
var shape = new Shape(); Object.seal(shape); shape.x = 50; shape.y = 50; shape.moveTo(120, 85); shape.draw(); // Drawing shape at: (120, 85) console.log(shape instanceof Shape); // true
‘use strict’;
var Shape = function () {
this.__x = 0;
this.__y = 0;
};
Shape.prototype = Object.create(Object.prototype, {
x: {
get: function () {
return this.__x;
},
set: function (value) {
this.__x = value;
},
enumerable: true,
configurable: false
},
y: {
get: function () {
return this.__y;
},
set: function (value) {
this.__y = value;
},
enumerable: true,
configurable: false
},
moveTo: {
value: function (x, y) {
this.x = x;
this.y = y;
},
writable: false,
enumerable: true,
configurable: false
},
draw: {
value: function () {
console.log("Drawing shape at: (" + this.x + ", " + this.y + ")");
},
writable: false,
enumerable: true,
configurable: false
}
});
Object.seal(Shape);
Object.seal(Shape.prototype);
var shape = new Shape();
Object.seal(shape);
shape.x = 50;
shape.y = 50;
shape.moveTo(120, 85);
shape.draw();
// Drawing shape at: (120, 85)
console.log(shape instanceof Shape);
// true
‘use strict’;
var Shape = $class({
__construct__: function () {
this.__x = 0;
this.__y = 0;
},
x: {
get: function () {
return this.__x;
},
set: function (value) {
this.__x = value;
}
},
y: {
get: function () {
return this.__y;
},
set: function (value) {
this.__y = value;
}
},
moveTo: function (x, y) {
this.__x = x;
this.__y = y;
},
draw: function () {
console.log("Drawing shape at: (" + this.x + ", " + this.y + ")");
}
});
var shape = new Shape({ x: 50, y: 50});
shape.moveTo(120, 85);
shape.draw();
// Drawing shape at: (120, 85)
console.log($is(shape, Shape));
// true
Features
- $class - it is used to define class
- $abstract_class - it is used to define abstract class
- $static_class - it is used to define static class
- $enum - it is used to define enum
- $interface - it is used to define interface
- $is - it is used to check type
- $create - it is used to create object
- $init - it is used to initialize object
- $module - it is used to define module
- $namespace - it is used to define namespace
- $extend - it is used to define method to exiting type
- $super - it is used to access parent's method
Conclusion
References
Saturday, June 1, 2013
Install classic gnome desktop in Ubuntu 12.04
sudo apt-get install gnome-panel
Saturday, May 18, 2013
Installing PhantomJS on Ubuntu 13.04
I have a virtual machine in which Ubuntu 13.04 (64-bit) version is installed. After a few attempts, I found the way how to install PhantomJS 1.9 to my virtual machine.
Steps are bellow:
~cd /Downloads wget https://phantomjs.googlecode.com/files/phantomjs-1.9.0-linux-x86_64.tar.bz2 sudo tar xvf phantomjs-1.9.0-linux-x86_64.tar.bz2 sudo mv phantomjs-1.9.0-linux-x86_64 /usr/local/share/phantomjs sudo ln -s /usr/local/share/phantomjs/bin/phantomjs /usr/bin/phantomjsTo check is installed successfully run such command:
phantomjs --version
Friday, May 17, 2013
How to install Sublime Text 2 on Ubuntu
Wednesday, May 15, 2013
SVG Loader
To get source code of svg loader go here.
Tuesday, February 19, 2013
NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence
The first part of the book concentrates on core concepts, including schemaless data models, aggregates, new distribution models, the CAP theorem, and map-reduce. In the second part, the authors explore architectural and design issues associated with implementing NoSQL. They also present realistic use cases that demonstrate NoSQL databases at work and feature representative examples using Riak, MongoDB, Cassandra, and Neo4j.
Tuesday, February 12, 2013
ASP.NET web api
Thursday, January 3, 2013
Disk space usage
df -HOutput:
Filesystem Size Used Avail Use% Mounted on /dev/sda1 33G 1.7G 29G 6% / udev 910M 8.2k 910M 1% /dev tmpfs 366M 246k 366M 1% /run none 5.3M 0 5.3M 0% /run/lock none 914M 0 914M 0% /run/shm /dev/sdc1 172G 4.8G 159G 3% /home/git/repositories /dev/sdb1 76G 1.3G 71G 2% /mnt/resource
Saturday, December 15, 2012
Installing PhantomJS on Ubuntu
I have a virtual machine in which Ubuntu 12.04 (32-bit) version is installed. After a few attempts, I found the way how to install PhantomJS 1.7 to my virtual machine.
Steps are bellow:
cd ~ get http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-i686.tar.bz2 sudo tar xvf phantomjs-1.7.0-linux-i686.tar.bz2 sudo mv phantomjs-1.7.0-linux-i686 /usr/local/share/phantomjs phantomjs --version
Saturday, December 8, 2012
Create your Own Git Server on Azure Cloud
Saturday, October 20, 2012
Meet the Raspberry Pi
I wanted to install raspberry by myself. I took an empty SD card and loaded to it Raspbian installer. Raspbian is OS dedicated to Raspberry Pi. You can find a manual how to install Raspbian here.
After long waiting and thew crashes I understood that installation failed.
I decided to choose different approach. I downloaded Raspbian image from here and used Win32DiskImager tool to write this image to SD card.
Finally, Raspbian started.
Sunday, August 26, 2012
Create a npm package
If you want to create and publish npm package you must complete theses steps:
1. Create a profile
Go to npm website and create a profile.
2. Create package.json file
Create a folder for your package and change the current directory to it:
mkdir my_package cd my_packageCreate package.json file:
{
"name" : "my_package",
"description": "package description goes here",
"version": "1.0.0",
"author": "Firstname Lastname <firstname.lastname@mail.com>",
"keywords": ["my_keyword1", "my_keyword2"],
"repository": {
"type": "git",
"url": "https://github.com/myuser/my_package.git"
},
"main" : "./lib/my_package.js",
"engines": {
"node": ">=0.8.8"
}
}
3. Link with npmLink your package with npm:
npm link4. Publish the package
Add a user:
npm adduserPublish a package:
npm publishIf you want to override published package you can user --force parameter:
npm publish --force
Monday, August 13, 2012
Say 'Hello world' using Node.js
Install the dependencies:
sudo apt-get install g++ curl libssl-dev apache2-utils sudo apt-get install git-coreDownload source code of version 0.8.8 from github:
git clone -b v0.8.8-release git://github.com/joyent/node.gitBuild and install node.js:
cd node sudo ./configure sudo make sudo make installTo get node.js version type:
node --versionCreate Hello world application
Create my-script.js file:
console.log("Hello world!!!")
Run the code:
node my-script.jsOutput:
Hello world!!!




