Archive for the 'PHP Talk' Category

Design Patterns: Wise Solutions to Save Time and Money

May 13, 2011


 
By Sibers Unix Developer Maxim Aksanov

Accompanied by Sibers PHP Developer Konstantin Sherpaev

Is it possible to quickly add features to your applications without having to completely rewrite them from scratch?

As a customer have you ever thought about the technical structure of your development project? Of course, you are probably thinking “Isn’t that your job?” Regardless of occupational designation, you are still probably aware that every application inherently has an abstract structure. Sooner or later you might want to change it, and thus you should have an understanding of at least the basic structure. A clear and good structure includes certain patterns of development, which is exactly what we are going to debate in this entry. These patterns, when used in the design of your application, can save significant development time and allow developers to use a number of useful features. So, what exactly are design patterns, and when they are useful for your tasks?

Design patterns are fixed templates which are used by developers for building a basic application frame. The frame choice depends on the specific features and purposes of the application. Since some application features are similar, developers create models for how to solve the most frequent design problems. These models are effective, internationally accepted design patterns. For these patterns work well, you need to consider what functions and supplements your application will need during the specification phase, as well as what you might want to add. In this phase developers can identify and reserve some “free places” for these components.

If developers ignore design patterns when creating application versions, adding every new feature, even a simple one, is going to become a very difficult task requiring a great deal of the developer’s time. In fact, it will result in rewriting the entire source functioning code. By sharing your project plans with your project manager upfront, your team will be able to change the code according to your desires with minimal difficulty and minimal time.

This particular issue has come to light a number of times with our own customers. One such example of this type of project involved an application that did not have any patterns in its structure. Each time our customer wanted to add a new feature, we had to add more and more work around. It was too complicated for us, but seemed very simple for the customer. He thought such minor additions could not possibly take hours of development. So, when the next feature addition was estimated to take 40 hours of work, we decided to apply design patterns. This task took 60 hours, but as a result we could add every new feature in just 4 hours. In addition, further support became simpler, and the customer, needless to say, was quite satisfied.

Another important advantage to using design patterns is their international recognition. These patterns speed up the transfer of your project to other developers in the event that you want to change the team, or want to make further additions with another provider some time after the project concludes. The new provider or developer will not have to spend hours working from scratch, and your money is going to be allocated more wisely.

However, the key to using patterns may is to use them wisely. The worst way to use patterns is to use them in all cases, with all variants in the same application in place, which will not be needed for some additions. This will actually increase the development time, and will result in complicating the code. Even worse, the next developers will have to spend much more time to repair the matter.

Types of Design Patterns

According to the Gang of Four, the authors of the book Design Patterns: Elements of Reusable Object-Oriented Software, there are 23 design patterns. These patterns are then divided into 3 functional categories: Creational, Structural, and Behavioral Patterns. Let’s briefly describe each and look at some case studies from our own practice.

Creational design patterns deal with object creation mechanisms, and attempt to create objects in a manner suitable to the situation. The basic form of object creation designed without patterns could result in design problems or excessive complexity. Creational design patterns solve this problem by controlling object creation.

Structural design patterns ease the process by finding a simple way to realize relationships between entities in the code.

Behavioral design patterns identify common communication patterns between objects and then realize these patterns. These patterns increase flexibility in carrying out communication between the objects.

Example 1

One project the Sibers team developed involved using the WebSpider module. WebSpider is a website downloading program that is used for analyzing and recording information in a database. For this project we completed multithread downloading by using a special algorithm.

Another application in the project required a different supplementary module — AvailabilityWatchet. While developing this application we found that this unit had the same structure and functionality as WebSpider, however the downloading algorithm was slightly different. In this case we had two possibilities: copy the process thread characteristics and correct them for new tasks, or redevelop the first module with a design pattern without code copying. It was a much wiser decision to follow the second variant, in case similar applications appear again and again. Therefore, we decided to apply a design pattern Factory Method. This pattern makes it possible to describe the logic of a process once in the basic technical class. In the new module we described a simple class which created concrete objects. As a result we created a technical class to manage abstract threads. In each module we had to briefly describe peculiarities of management and how the application met new needs.

Thus, the Creational design pattern was most beneficial in this situation.

Even more importantly, we were able to greatly simplify the addition of new units with similar structures without having to spend any time on new coding, as all we needed to do was use the design pattern established in our code.

The design pattern used allowed us to decrease the amount of code, making it more structured and readable. This meant there was less potential for developer mistakes. Overall, the process was a great advantage for us as it decreased the development time for further modules.

Example 2

Another of our case studies involved developing a site downloader which required data to be transferred in the same format. PHP language was used in the development process.

Downloading was needed to accomplish this task, and was started repeatedly. Since the design pattern using downloader had to be initialized for every feature and every time, be it Loginer or Extractor, a solution was needed as the process was quite inconvenient.

We then used Creational pattern Singleton for the downloader, which had a request generation method description. This downloader’s major advantage was logging request data, thus allowing us to process several parallel requests.

***

These cases clearly show the necessary and beneficial usage of design patterns. When we began analyzing the excessive use of patterns in our practice, we only came up with a handful of cases where developers erroneously used a certain type of a pattern. The effect was obvious as the application had a big code dimension, experienced trouble with testing, and worked with objects that required many unnecessary actions. If you see similar symptoms in your project, it is a sign of using an incorrect pattern. However, this does not mean that all the patterns have to be removed. When developers replace just the pattern used erroneously with the correct pattern, everything ran smoothly, and worked effectively.

By now it should be clear how using appropriate design patterns can simplify the process of development, save time and money, as well as improve the functionality of the application. You should also be aware that developing such patterns can take some time, but the extra cost will most definitely pay for itself in the long run. If the code is written without such patterns, which may be less expensive upfront and may seem unnecessary for some customers, any further desirable features in the application may result in many hours of development time, in spite of being consider “minor” or negligible. Now it’s time for you to make a decision as to whether to allow developers to use these suggested design patterns for your project or not.

Custom GoogleMaps integration

December 17, 2008

By PHP Developer Alexey Zabaykin

How to list clients’ feedback in a way that shows that you have many clients and they are spread globally?

Thanks to the huge amount of feedbacks, our previous edition of References page turned to look like the Star Wars story-telling.

We decided that Google Maps will do the job. I should note that the site engine, developed by Sibers, was created using Sophit framework. This engine is very flexible and pretty simple for creating administrative solutions and fully separates HTML templates from PHP code. That’s why creation of PHP administrative part doesn’t cause any problems and webmasters enjoy a huge area for professional activities.

gmapref

The next point was to research the necessary interactions with Google Maps. There is a lot of abilities provided by Google to change types of appearance and various features. So, to escape the mess, I investigated a bit in order to create the optimal solution. Thus, here is a list of crucial moments of creating our References page.

Backend

Simply put, we have to insert locations and link them with needed information. Administrator has two possibilities to manage the locations: automatically, through the function

geocoder.getLatLng()

- looks for the place by name only – and manually with function

GEvent.addListener(map, ‘click’, mapClick)

- sets latitude/longitude by a click on map; coordinates then are transferred into the form by

mapClick function.

Displaying

Ok, the administration form is done. Now, in order to display feedbacks on the map, we pass them to javascript in the cities array and Google Maps start to populate with our thankful customers. For further interactivity, let’s make the bubble images change when mouse hovers it.

GEvent.addListener(marker, “mouseover”, function() {
marker.setImage(pic_hand_up.src);
});
GEvent.addListener(marker, “mouseout”, function() {
marker.setImage(marker.getIcon().image);
});

And one more tweak, image preloading:

var pic_hand_up = new Image()

Now the little green person gladly greets us and does not disappear during first loading. The customer reference can be quite large, therefore its content dynamically loads by clicking on the icon:

_getFullReferences(city_id)

Also, references with phone numbers are displayed immediately below the map. When clicking on the address line, the map centers on this location via method map.setCenter()

Time to check it by yourself: http://www.sibers.com/portfolio/references/

When Coding Limitations Make Sense

December 12, 2007

gavrilov.jpg By Sibers CTO Andrey Gavrilov

Some time ago I ran across such or similar articles. In general, their idea is that we don’t need template engines in PHP since PHP is template-driven by itself (obviously, in fact, that’s true not only about PHP because there exist JSP, PSP etc. in other technologies). And of course, in all articles of this sort they throw mud at Smarty, the most popular template engine.

So what I am saying is that authors of these articles have no idea what template engines are for. But I agree that Smarty and 90% of similar engines suck because their authors have no idea, too.

A template engine is needed not for separating content from functionality: a good programmer can easily do this in pure PHP. We need templates in order not to allow designers touch any of server functionality – and no Smarty with its too rich feature set can help us here.

If you find this observation far-fetched, I can assure that such a requirement appears in every large project whose specifications I reviewed. No large well-established e-business company can permit their designers staff to get full access to system’s functionality – something that most template engines still allow! Needless to say about sites that allow users setting up their own themes.

Obviously, you can return: if you wanna set up your design, use CSS. That’s all fair, except for the fact that it raises some inconveniences:

  • Page should contain all elements that it should display (since design is applied on client’s side). As a result, you get cumbersome dinosaur-like htmls.
  • If a CSS file hasn’t loaded for any reason, you see something frightful. Think of large pages that are shown underloaded with all hidden elements that are displayed until CSS is loaded.
  • For proper customization, it’s vital to use div-based design that not everyone likes.

So, an ideal template engine is the one that allows working only with data that was fed into it – and nothing more.

What Life in Linux Looks Like

May 18, 2007

by Valery Makarenko, PHP Senior Developer

Linux has been implemented on my computer for about a month, and this is what comes out of it.

1. Stability. It really exists. Applications come and go, but the system keeps working.

2. Convenience. Open source says for itself. If you stay in KDE (Desktop Environment), for example, the user interface is the same throughout.

3. Compatibility. As for the compatibility of documents formats, OpenOffice performs its job well enough. At least it can read and create the main types of Office XP documents: DOC, XLS, PPT.

4. Programs. Following is a list of software with some comments and the Windows analogues for reference.

  • Instant messenger: qip

o SIM fully satisfies all the needs of instant communication (the ICQ protocol) without any problems with character encoding, etc. Some minor snarks are likely to depend on the SIM version and KDE, which can be overcome with time.

  • Web browser: Mozilla Firefox / Opera / IE

o Mozilla Firefox / Opera. I didn’t try Opera as Firefox fully satisfies all requirements on surfing the net and developing applications (Java script).

  • Sniffers: HTTPAnalyzer, ServiceCapture (AMF)

o Wireshark capture everything possible; AMF doesn’t understand and requires special root privileges to run.

  • File manager/editor/archiver/ftp/scp/… – FAR

o bash / MC / Krusader. The console is unavoidable. Forget about the universal character of FAR, and you’ll enjoy MC. It is principally similar, but substantially yields in convenience.

Krusader seems to be quite raw and fails to work without any serious reasons.

As for Konqueror, in fact, it’s a good analogue of Windows Explorer.

  • MySQL: EMS MySQL manager

o MySQL Tools created by MySQL team. The GUI set of MySQL Tools utilities allows administrating MySQL server, manipulating tables and database entries and debugging SQL quieries. It also includes a built-in Help on MySQL. He disadvantages are the product being somewhat raw and limited to only 5 and higher versions of MySQL.

  • E-Mail: TheBat

o KMail, ThunderBird. Both mail clients are worthy. If you stick to KDE, KMail seems to be a good variant (only it doesn’t support different mail accounts and requires additional filters tuned). However, both applications are suitable for purposes of everyday communication.

  • Office: MS Office (Word, Excel, Powerpoint)

o OpenOffice is fully compatible with MS Office XP, which is enough for everyday work. There might appear some problems with difficult Exel documents with scripts inside, but I haven’t face them yet.

  • Dictionary: Lingvo

o StarDict can be plugged into the system quite conveniently. Moreover, it has a wide choice of dictionaries.

  • Hardware monitoring: DTemp/MBMonitor

o GKRellm performs its functions well enough, has a lot of skins.

  • Organizer: WinOrganizer, ATNotes

o KNotes / Kwallet are almost identical to their Win-analogues, KWallet being embedded into KDE and saving all the passwords, which can be used without the user’s interference.

  • SVN client: Tortoise SVN

o KSVN is a good GUI-SVN client with all the standard operations like CheckIn, CheckOut, Diff-view. It can be embedded into Konqueror similar to TortoiseSVN.

  • CASE: Enterprice Architect

o Umbrella / ArgoUML (Java) / DIA. The new DIA allows drawing diagrams and there is a choice between it and Umbrella; ArgoUML is a bit slow as it is written in Java.

  • Multimedia (audio): winamp

o Mplayer / BMP. Perform their functions perfectly.

  • Multimedia (images): ACDSeee, Photoshop

o gwenview, digiKam / Gimp. The pair gwenview and digiKam are quite convenient for viewing, cataloguing and simple picture processing. Gimp is also a powerful tool, but Photoshop ultimately wins the competition.

  • IDE: Eclipse (Java)

o Eclipce (Java) in my personal opinion is a highly problematic solution, slow and hanging. KDevelop – KDE package seems to be much more convenient with all its possibilities – projects, class browser, folding, code completion, etc.

5. Challenges.

  • Absence of Internet Explorer presents a problem which can be solved, probably, only via virtualization. (Wine, VMWare, etc.). The problem is not in surfing the net but in developing JavaScript applications and making HTML layouts, which is supposed to distinguish between the browsers.
  • Java works a bit unsteadily, much slower and with more snarks. Firefox failed to customize for working with Java applets.
  • Printer won’t work properly as well.

In general, we are working on these challenges and hope to overcome them in the near future.

Sibers Are Playing Their Brain Muscles

December 22, 2006

You probably know how people love to compete with each other? All those machos out there are always discussing whose muscles bigger, legs stronger and etc. Among science geeks the discussion is usually held about whose brains are better in this or that scientific field, that’s why they produce so much scientific papers each year.

Well, that sort of competition could not left out our developers as well. So we decided to show you, dear reader, that among our IT crowd there are also machos-developers, who love to test their wits on the website, famous by its test conducted among professionals in many fields, called Brainbench. This site is delivering easy-to-use assessment products that predict success on the job. This website exists for many years (founded in 1998), and it is not a laughing matter, when some of its users gain high ranking.

Two members of our Sibers team decided to check out how smart they have become while working at our company and took tests in their fields of expertise. And behold! They gained pretty serious rating in those tests. One of them is our Flash Team Leader, Alexander Nemtsov. He took Flash Development test and found out that he ranks 12 among top Brainbench users from Russian Federation, who took the same test.

Another hero of the day is our Senior PHP Developer, Alexey Kupershtokh. He gained number 13 ranking among top Brainbench users from Russian Federation, who participated in PHP test.

To Revise Ideas of Improving Ruby

November 28, 2006

by Sibers CTO Andrey Gavrilov

After revising my ideas on writing functions from the previous post, I came to the conclusion that previously described function arguments could still cause problems. First of all, the lines with supposedly defined iterators will suffer. Even if we create some additional iterators, anyway func val and func (val) being not identical will be troublesome.
Another idea, a crazier one, dawned upon me – that parentheses are optional as they function as a grouping operator as in expressions. Then the arguments in writing without parentheses are still divided by comas. To avoid errors we introduce the following conventions:

•Expression interpretation doesn’t depend on defining functions. Which argument belongs to which function is defined only by calling the function. It will let us avoid errors in calls while changing the function format.
•Expression interpretation should be such as to obtain any variants of argument distribution between functions by means of parentheses.
Hence we assume that the absence of parentheses is identical with the widest parentheses.

Examples:
func1 func2 arg are interpreted only as func1(func2(arg)) as they don’t include a coma;
func1 func2 arg1, arg2 are interpreted as func1(func2(arg1), arg2).
In order to transmit arg2 to func2, it should be explicitly shown with parentheses:
func1 func2 (arg1, arg2)

Seems to work correctly, doesn’t it?

Source

To Writing Functions in Ruby w/o Parentheses

November 24, 2006

by Sibers CTO Andrey Gavrilov

One of the requirements to scripting languages is an opportunity to call a function without using parentheses (e.g., print “test” instead of print (“test”)). The problems arising out of this are obvious as construction func1 func2 “test” with variable parameters can be treated either as

func1(func2("test")) or as func1(func2(),"test") .

Ruby solves the problem by informing about errors just noticing a slightest ambiguity:

def func1(name)
puts name
end

def func2(name)
return name
end


func1 func2 "test"
-:9: warning: parenthesize argument(s) for future version

def func1(name1, name2)
puts name1 + name2
end

def func2()
return "test1"
end

func1 func2 "test2"
-:19: warning: parenthesize argument(s) for future version

It is absolutely right of Ruby to do so as otherwise adding an optional parameter to the function could cause errors in its calling. It looks, though, as a patch to potentially holed syntax.
The most logical solution seems to use only one argument in the form without parentheses. Anyway, using such a form for a few arguments doesn’t improve readability. In such a case form func1 func2 "test" is interpreted only as func1(func2("test")) . The solution is strict but lacks logic as well.
If I wrote a scripting language:
•Form func arg with "arg" being one argument would be the only form to call the function.
•Form ("a", "b", name:"c", "d") would be vocabulary builder

[0] => "a",
[1] => "b",
["name"] => "c",
[4] => "d",

•So when calling a function, it uses its argument as vocabulary, i.e. it tries to fill its arguments from the vocabulary first by name, then by the serial number and finally by the default value. If some of the arguments are left empty, an error is reported.
•To make constructions of the form print "test" work, I’d define property [0] in the class Object, which would point the object itself by default. Thus, when calling a function with one argument without parentheses, it would refer to the object as vocabulary and get it as the first argument (provided [0] is not redefined as in the case with list types). If a function has two arguments and [1] or a property with the name of the argument is not additionally defined, an error is reported.

Sibers FM

October 16, 2006

At Sibers, we are not obliged to devote 100% of us solely to work, every day. Work should be fun and even more if you can be helpful to your co-sibers.
Walking through our offices, you can often see people sitting with their headphones on. So I decided to launch a radio station to control their minds! :)

Now if you’re in the network, you can just type http://design:8000 (design is the name of my computer) and listen to the best Drum&Bass tracks from my PC.

I want to show all the sides of Drum&Bass and variety of trends. Some of my colleagues forejudge it, but in fact they heard only one or two tracks that didn’t fit them. But Drum&Bass is so various.

There are a lot of trends and styles in Drum&Bass from Atmosferic/Intelligent till DarkSide, LiquidFunk, TechStep, ClownStep, NeuroFunk all this Drum&Bass, so tracks could be as light and melodic as very fast and hardcore.

Of course my own preference has a bit influence on what is playing at current time. Mostly, I’m playing massive tracks with smashed baseline. Some of my colleagues noticed that working with this music is much more efficient. We’ll have to check it with hour reports for this month :)

Follow

Get every new post delivered to your Inbox.