Saturday, August 27, 2011
Agile and SOA Architectures
i would like to share with you SOA Architectures experiences, opinion, initiatives, threads an so on.
I am an SOA Architect with projects experience in different companies Europe wide.
I am also an SOA Architect and Security Specialist at arcitura.com formerly SOASchool.com as well as SOA Trainer.
In one of the last experience I am facing with agile methodologies not supported by an equally agile architecture. I am convinced a good agile model to drive changes should be combined with an IT architecture that allows the changes to be quickly implemented not olny at process level.
Many things there are to say on this topic, but i would like first to ask my readers if you may kindly want to share your view. Thanks :)
Saturday, October 25, 2008
Antonio for OU
Hi visitors,
my name is Antonio. I´m an electronic and software engineer. I have studied in Italy and I have been living in Switzerland since 2007. I have studied at OU in 2008/09 for the course M865.
I find writing a chunk for a book a challenge and also a pleasant hobby. I hope to get your feedback, i will do the same if you wish...
Good Luck to everybody!!!!
Note that this is not a complete version, in particular i´m going to improve the code intending and relative font!!
The chunk 75 tries to explain how to manipulate pixel in faster way than the normal manipulation. The objective is to explain the topic through an object-oriented programming approach as well.We are going to explain the basic faster-pixels Processing functions and then trough an OOP we write a program to show a real case to generate something like a shimmer effect.
In order to manage pixels in efficient way, Processing makes available some language structures that are built to speed the pixel calculations up.We will be showing these structures through snap pieces of code and then within a whole program. In order to reuse the code here, copy/paste into a word processor (e.g. MS-WORD) before and from there into your sketchbook window and hit run. Do not copy direct into your sketchbook as you will have text formatting problems.
The pixel is the smallest image unit on the screen that you can manipulate. In order to identify a pixel on the screen we need two Cartesian coordinates x, y (remember we are talking about 2D images, otherwise we should extend the space in 3-dimensions although the screen remains 2D) and eventually another numeric value or object to define its colour.
For example the following snap code shows how to set a pixel in the middle (px, py position) of the screen with the colour c (note c is a color data type defined in the Processing language). You are going to see a very little white point in the middle of the black screen!!
void setup(){
size(500,500);
background(0);
smooth();
int px = width/2;
int py = height/2;
color c = color(255,255,255); //red, green and blue components respectively set(px,py,c);
}
The code above uses the function set(x,y,c) to draw the pixel at the position (x,y) with the color c (white). The set() function encapsulates some lower-level java functions that enables the pixel manipulation. This means that for each set() call corresponds a bunch of calls to other lower-level java functions. It could be intuitive that the process to manipulate many thousands of pixels could be expensive and have an impact on the performance of a program that manipulates dynamic imagines.
The three Processing structures to manipulate pixels in a faster fashion are two functions and one array. These structures are correlate one other and they are loadPixels(), updatePixels() and pixels[].The first two are functions the third is an array.The loadPixels() loads the pixels of the display window into a built-in global variable named pixels[].
It organizes the pixels of the display window as a sequence of height rows of width elements long into the array; for example a display window of 500x500 has the pixels array (width*height) of 250,000 elements long.
The following snap code prints out on the screen the pixels array length:
size(500,500);
loadPixels();
print(pixels.length);
You get 250,000.
It is easy to understand now that if you want “manipulate” the pixel (x,y) on the screen you can make it by accessing at the element:
pixels[(y-1)*width+x-1]
(note that the array has the first element at the index 0, instead the display window has the first row and the first column starting from 1).
The pixels[] array organizes each pixel colour in memory.
You may want, for example, to set the pixel at the position (x,y) with the colour yellow, you can make it by adding the following logic in your code:
pixels[(y-1)*width+x-1] = color(255,255,0);
where width is the width of your display window.
Note that you are not constrained to set a colour only with the data type color (e.g. you may want to set up a pixel with the fill() function).
The last “faster” function provided is updatePixels() that simply updates the screen with the pixels you have stored in the array.
Note that although loadPixels() and uploadPixels() functions do not give any “visible” result they must be called prior and after utilizing pixels[] respectively, otherwise you do not get any error but the behaviour is not the one you´re expecting.
The object-oriented program for this chunk requires some knowledge about both the UML notation and “substitution principle”.
We start showing you the sketch UML class-diagram and then we are going to describe each class.
The OOP structure for this chunk is showed in the following UML class-diagram:
As you can see from the Figure 1, we have a structure of classes composed by two levels: the high-level one is abstract and the low-level one is concrete.
For now we can ignore the classes Runnable and ShimmerAnimation in that they are only used to start the shimmer effect and Runnable is a pre-defined class.
This is an UML class-diagram representation. (The UML stands for Unified Modeling Language and it is an open standard language used to document, visualize, specify and model software systems artefacts during their lifecycle).
The high level of the diagram is composed by interfaces or abstract classes.
The interface establishes the “contract” that whatever concrete class that implement it must realize in terms of what it needs to implement but not how….
You can see dashed arrows that represent dependency relations. For example the ShimmerController interface uses in its methods both the interfaces ShapesDataStore and Shape. These dependencies are actually realized in the code through local variables, input or output method parameters (we are going to see this in the code below).
The second level of the hierarchy in the diagram is composed by concrete classes, that is, classes that implement the body of all of the methods declared in the interface.
This means that whatever class that implements or realizes those interfaces can be plugged into this structure. It is also said that these classes specialize the interfaces type.
The advantage to have dependences at the abstract level rather than at the implementation one, is that we can take advantage of the OOP “substitution principle”. In few words the principle states that at run-time any object reference variable (or handle) can be assigned to any type that extends or implements it (this is the base for something beautiful called in OOP Polymorphism).
For example an handle of type Shape can be assigned at run-time to a SquareShape or CircleShape and so on provided that these objects implement or extend the class/interface Shape.
This is very useful since it enables us to design software without worry about abstraction and its implementation at the same time, these concepts can be decoupled.
The first interface we describe is the simple Shape:
interface Shape{
void drawShape();
ShapesDataStore getShapesDataStore();
}
It contains two methods : one is for drawing a shape and the other one is to get a “store” object that contains shapes “information”.
Essentially in this sketch we are going to generate a sequence of shapes overlapped one other. The store will contain for each shape a position (x, y) and a dimension (e.g. the center position and the side dimension for a square).
The stored information will be used afterward to generate the shimmer effect.
The method getShapesDataStore() just return a reference at the store object.
The second interface described is ShapesDataStore :
interface ShapesDataStore {
int getArrayLength();
int getXVertex(int index);
int getYVertex(int index);
void setXVertex(int index,int x);
void setYVertex(int index,int y);
void setSideDimension(int index,int sideDim);
}
This interface has methods to access at the store object. These are methods to get and set x and y position of a shape as well as a dimension.
Note an index as method input parameter, this is because this object is an indexed store (array-like).
The third interface described is ShimmerController:
interface ShimmerController{
Shape getShape();
ShapesDataStore getShapesDataStore();
void startShimmer();
}
The first two methods are to get the references to the Shape and ShapeDataStore objects respectively.
The last method is a method to start the shimmer effect.
The fist concrete class we describe is the SquaresDataStore. This class implements the ShapeDataStore interface. This class represents a store of square shapes. So the semantic it gives to its methods is for x and y values the vertex position and for dimension the side length.
If we needed to store data for the circle shape, the semantic could be for x and y values the center position and for dimension the radius length.
class SquaresDataStore implements ShapesDataStore{
int [][] arrayposition; //the real store data structure
//constructur
SquaresDataStore(int numElement){
arrayposition = new int [numElement][3];
}
int getArrayLength(){
return arrayposition.length;
}
int getXVertex(int index){
return arrayposition[index][0];
}
int getYVertex(int index){
return arrayposition[index][1];
}
int getSideDimension(int index){
return arrayposition[index][2];
}
void setXVertex(int index,int x){
arrayposition[index][0] = x;
}
void setYVertex(int index,int y){
arrayposition[index][1] = y;
}
void setSideDimension(int index,int sideDim){
arrayposition[index][2] = sideDim;
}
}
As you can see, the store is implemented by means of a bi-dimensional array (2x2 matrix) of integer type. Its size is numElement x 3 where numElement represents the number of shapes we want store, and 3 are the places to store x,y and dimension values respectively. The methods´ body is quite simple to understand.
The concrete class SquareShape is a specialization of the Shape interface. This class is used to draw a sequence of overlapped squares of same center position but side length step by step decreasing (so one square into another) and each fill colour having a fade step by step more intense.
By design this class should have a reference to the ShapeDataStore object since it implements the Shape interface. In fact in the code it has an object reference variable of ShapeDataStore type.
Here is where the substitution principle comes to play. Since the SquareShape class draws squares it needs to store data in a SquareDataStore object. For this reason at run time a SquareDataStora object will be created and assigned to the reference variable ShapeDataStore. This is allowed since SquareDataSore object is a ShapeDataStore type.
class SquareShape implements Shape{
int index = 0;
Point p;
int dimension;
float fade = 0;
int offset;
SquaresDataStore sd;
float fillCol = 0;
float shift = 1.0;
int shimmerLength;
// constructor
SquareShape(int width, int height, int shimmerLength){
this.fade = 255.0/(width/2.0/shift);
sd = new SquaresDataStore(round(width/2/shift));
this.dimension = width;
this.shimmerLength = shimmerLength;
translate(width/2, height/2);
p=new Point(-width/2,-height/2);
}
ShapesDataStore getShapesDataStore(){
return sd;
}
void drawShape(){
while(p.x<0){
fill(fillCol,fillCol,fillCol);
fillCol+=fade;
if(dimension<width-2*(shimmerLength+1)){
sd.setXVertex(index,p.x);
sd.setYVertex(index,p.y);
sd.setSideDimension(index,dimension);
index++;
}
rect(p.x+=shift,p.y+=shift,dimension-=shift,dimension-=shift);
}
}
This class generates a number of width/2/shift squares. Each square data (x,y and side length) is stored into the SquareDataStore object, here created. The squares are drawn from the biggest one with dimension=width, until the smallest one with dimension=shift. The dimension is step by step decreased of a shift amount until the x position remains negative (note that the Cartesian plane is translated).
The processing rect() function is used to draw squares.
You can also notice that the fill colour of each square is increased of a fade amount.
The following figure (“UFO ship approach” ) is the result of the draw() method:
The class we are going to describe now is the one that uses the Faster Pixels functions and it is the more complex since it involves some math calculus. This class in fact is used to generate a kind of shimmer effect on top of the “UFO ship approach” figure 2.
As showed in Figure 1, the SquareShimmerController class has two reference variables to the ShapesDataStore and Shape classes that will be assigned at run time (substitution principle) at SquareDataStore and Square object types respectively.
class SquareShimmerController implements ShimmerController{
// reference variables
SquareShape shapeRef;
SquaresDataStore sd;
int shimmerLength;
int width;
int xPos;
int yPos;
int index;
int dimension;
int offset;
//constructor
SquareShimmerController(int width, int height, int shimmerLength, Shape sh){
shapeRef = (SquareShape)sh;
sd = (SquaresDataStore)shapeRef.getShapesDataStore();
this.shimmerLength = shimmerLength;
this.width = width;
offset = (height/2)*width+width/2;
}
Shape getShape(){
return shapeRef;
}
ShapesDataStore getShapesDataStore(){
return sd;
}
void startShimmer(){
loadPixels();
color c = color(random(255),random(255),0);
index = round(random(0,sd.getArrayLength()-1));
xPos = sd.getXVertex(index);
yPos = sd.getYVertex(index);
dimension = sd.getSideDimension(index);
for(int j=(yPos-1)*width+xPos-1;j<((yPos-1)*width+xPos-1)+shimmerLength;j++){
pixels[j+offset] = c;
pixels[j-shimmerLength+offset] = c;
pixels[j+dimension+offset] = c;
pixels[j-shimmerLength+dimension+offset] = c;
pixels[j+dimension*width+offset] = c;
pixels[j-shimmerLength+dimension*width+offset] = c;
pixels[j+dimension*width+dimension+offset] = c;
pixels[j-shimmerLength+dimension*width+dimension+offset] = c;
}
for(int i=0;i<shimmerLength;i++){
for(int j=(yPos-1)*width+xPos-1;j<((yPos-1)*width+xPos-1)+1;j++){
pixels[j+offset+i*width] = c;
pixels[j+offset+(i)*(-width)] = c;
pixels[j+offset+dimension+i*width] = c;
pixels[j+offset+dimension+(i)*(-width)] = c;
pixels[j+offset+dimension+i*width] = c;
pixels[j+offset+dimension+(i)*(-width)] = c;
pixels[j+offset+i*width+dimension*width] = c;
pixels[j+offset+(i)*(-width)+dimension*width] = c;
pixels[j+offset+i*width+dimension*width+dimension] = c;
pixels[j+offset+(i)*(-width)+dimension*width+dimension] = c;
}
}
updatePixels();
repaint();
}
}
Essentially the startShimmer() method draws on top of the four vertexes of each square, randomly selected in the store, four cross randomly coloured. Therefore if you call n-times the method, you get 4 x n-times crosses randomly coloured on the vertexes of the n squares randomly chosen. In figure 3 is showed what you see after few executions of this method.
The colour is chosen randomly with the following code:
color c = color(random(255),random(255),0);
//only red and green components to have brighter colours
A reference to the SquareDataStore object is passed in the constructor.
The startShimmer() method calls the uploadPixels() function to upload in memory all the display pixels and randomly it selects an index of the store to load the respective x,y and side length values into the local variables xPos,yPos and dimension.
In order to draw four crosses on the vertexes of a square, the pixels array is used with simple math calculus to figure out the indexes of the array for the pixels need to be updated. The length of each cross segment is two times the shimmerLength parameter. Note the cross has vertical and horizontal segments with the same length as well.
The following for loop is used to draw only the horizontal segments of the four crosses:
for(int j=(yPos-1)*width+xPos-1;j<((yPos-1)*width+xPos-1)+shimmerLength;j++){
pixels[j+offset] = c;
pixels[j-shimmerLength+offset] = c;
pixels[j+dimension+offset] = c;
pixels[j-shimmerLength+dimension+offset] = c;
pixels[j+dimension*width+offset] = c;
pixels[j-shimmerLength+dimension*width+offset] = c;
pixels[j+dimension*width+dimension+offset] = c;
pixels[j-shimmerLength+dimension*width+dimension+offset] = c;
}
In fact one segment of length two times shimmerLength with center at the position j is drawn with the following code (one segment of shimmerLength at the right of the point j and one at the left as well):
for(int j=(yPos-1)*width+xPos-1;j<((yPos-1)*width+xPos-1)+shimmerLength;j++){
pixels[j+offset] = c;
pixels[j-shimmerLength+offset] = c;
...
}
This snap code is extended to draw the other three segments on the rest vertexes of the square of length dimension, in fact the above two lines of code are to draw only one horizontal segment. Note we need a for loop of shimmerLength times to draw 2 x shimmerLength pixels.
The variable offset just takes in account that the Cartesian axis are translate of (width/2, height/2). Note the left upper point of the screen remains always mapped at the index 0 in the pixels array.
Likely the following for loop is used to draw the vertical segments of the 4 crosses:
for(int i=0;i
pixels[j+offset+i*width] = c;
pixels[j+offset+(i)*(-width)] = c;
pixels[j+offset+dimension+i*width] = c;
pixels[j+offset+dimension+(i)*(-width)] = c;
pixels[j+offset+dimension+i*width] = c;
pixels[j+offset+dimension+(i)*(-width)] = c;
pixels[j+offset+i*width+dimension*width] = c;
pixels[j+offset+(i)*(-width)+dimension*width] = c;
pixels[j+offset+i*width+dimension*width+dimension] = c;
pixels[j+offset+(i)*(-width)+dimension*width+dimension] = c;
}
}
Here we need to move the array index with +/-i*width amount to update pixels on a vertical segment.
Finally the update() function and repaint() are called to update the pixel array and to force the figure to be drawn on the screen any time.
The ShimmerAnimation class it is a very simple class used just to call the startShimmer() method of the SquareShimmerController class in an infinite loop interrupted each 30ms. Essentially it implements a thread that goes to sleep for 30ms for each execution.
This is all the code for this sketch:
void setup(){
size(400,400);
background(0);
smooth();
noStroke();
int shimmerThick = 8;
Shape sShape = new SquareShape(width,height,shimmerThick);
sShape.drawShape();
ShimmerController sController = new SquareShimmerController(width,height,shimmerThick,sShape);
new ShimmerAnimation(sController);
}
interface Shape{
void drawShape();
ShapesDataStore getShapesDataStore();
}
interface ShapesDataStore {
int getArrayLength();
int getXVertex(int index);
int getYVertex(int index);
void setXVertex(int index,int x);
void setYVertex(int index,int y);
void setSideDimension(int index,int sideDim);
}
interface ShimmerController{
Shape getShape();
ShapesDataStore getShapesDataStore();
void startShimmer();
}
class SquaresDataStore implements ShapesDataStore{
int [][] arrayposition;
//constructur
SquaresDataStore(int numElement){
arrayposition = new int [numElement][3];
}
int getArrayLength(){
return arrayposition.length;
}
int getXVertex(int index){
return arrayposition[index][0];
}
int getYVertex(int index){
return arrayposition[index][1];
}
int getSideDimension(int index){
return arrayposition[index][2];
}
void setXVertex(int index,int x){
arrayposition[index][0] = x;
}
void setYVertex(int index,int y){
arrayposition[index][1] = y;
}
void setSideDimension(int index,int sideDim){
arrayposition[index][2] = sideDim;
}
}
class SquareShape implements Shape{
int index = 0;
Point p;
int dimension;
float fade = 0;
SquaresDataStore sd;
float fillCol = 0;
float shift = 1.0;
int shimmerLength;
// constructor
SquareShape(int width, int height, int shimmerLength){
this.fade = 255.0/(width/2.0/shift);
sd = new SquaresDataStore(round(width/2/shift));
this.dimension = width;
this.shimmerLength = shimmerLength;
translate(width/2, height/2);
p=new Point(-width/2,-height/2);
}
ShapesDataStore getShapesDataStore(){
return sd;
}
void drawShape(){
while(p.x<0){
fill(fillCol,fillCol,fillCol);
fillCol+=fade;
if(dimension<width-2*(shimmerLength+1)){
sd.setXVertex(index,p.x);
sd.setYVertex(index,p.y);
sd.setSideDimension(index,dimension);
index++;
}
rect(p.x+=shift,p.y+=shift,dimension-=shift,dimension-=shift);
}
}
}
class SquareShimmerController implements ShimmerController{
// reference variables
SquareShape shapeRef;
SquaresDataStore sd;
int shimmerLength;
int width;
int xPos;
int yPos;
int index;
int dimension;
int offset;
//constructor
SquareShimmerController(int width, int height, int shimmerLength, Shape sh){
shapeRef = (SquareShape)sh;
sd = (SquaresDataStore)shapeRef.getShapesDataStore();
this.shimmerLength = shimmerLength;
this.width = width;
offset = (height/2)*width+width/2;
}
Shape getShape(){
return shapeRef;
}
ShapesDataStore getShapesDataStore(){
return sd;
}
void startShimmer(){
loadPixels();
color c = color(random(255),random(255),0);
index = round(random(0,sd.getArrayLength()-1));
xPos = sd.getXVertex(index);
yPos = sd.getYVertex(index);
dimension = sd.getSideDimension(index);
for(int j=(yPos-1)*width+xPos-1;j<((yPos-1)*width+xPos-1)+shimmerLength;j++){
pixels[j+offset] = c;
pixels[j-shimmerLength+offset] = c;
pixels[j+dimension+offset] = c;
pixels[j-shimmerLength+dimension+offset] = c;
pixels[j+dimension*width+offset] = c;
pixels[j-shimmerLength+dimension*width+offset] = c;
pixels[j+dimension*width+dimension+offset] = c;
pixels[j-shimmerLength+dimension*width+dimension+offset] = c;
}
for(int i=0;i<shimmerLength;i++){
for(int j=(yPos-1)*width+xPos-1;j<((yPos-1)*width+xPos-1)+1;j++){
pixels[j+offset+i*width] = c;
pixels[j+offset+(i)*(-width)] = c;
pixels[j+offset+dimension+i*width] = c;
pixels[j+offset+dimension+(i)*(-width)] = c;
pixels[j+offset+dimension+i*width] = c;
pixels[j+offset+dimension+(i)*(-width)] = c;
pixels[j+offset+i*width+dimension*width] = c;
pixels[j+offset+(i)*(-width)+dimension*width] = c;
pixels[j+offset+i*width+dimension*width+dimension] = c;
pixels[j+offset+(i)*(-width)+dimension*width+dimension] = c;
}
}
updatePixels();
repaint();
}
}
class ShimmerAnimation implements Runnable{
ShimmerController sc;
ShimmerAnimation(ShimmerController sc){
this.sc = sc;
Thread t = new Thread(this);
t.start();
}
void run(){
while(true){
sc.startShimmer();
try{
Thread.sleep(30);
}
catch(InterruptedException e){}
}
}
}
The figure 4 shows the final result "UFO ship landing" of this sketch: