czwartek, 26 lipca 2007

Software Engineering Quotations

Jeżeli nie lubisz cytatów - nie czytaj tego posta :) Poniżej zamieściłem najlepsze cytaty dotyczące informatyki (głównie SE) jakie znalazłem. Większość z nich jest naprawdę sławna ;)

Software Engineering

You know you've achieved perfection in design, not when you have nothing more to add, but when you have nothing more to take away.
- Antoine de Saint-Exupery

Programming is fun, but developing quality software is hard. In between the nice ideas, the requirements or the "vision", and a working software product, there is much more than programming.
- Philippe Kruchten, Foreword of Applying UML and Patterns
[dodano 2007.08.05]

If I had eight hours to chop down a tree, I'd spend six sharpening my axe.
- Abraham Lincol

The open secrets of good design practice include the importance of knowing what to keep whole, what to combine, what to separate, and what to throw away.
- Kevlin Henny

There is nothing permanent except change.
- Heraclitus

Without requirements or design programming is the art of adding bugs to an empty text file.
- Louis Srygley

You can't have great software without a great team, and most software teams behave like dysfunctional families.
- Jim McCarthy

Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves.
- Alan Kay

If we asked the customers what they wanted, it would be devastating for the project.
- Team lead on a project that shall remain nameless.

Part of the reason so many companies continue to develop software using variations of waterfall is the misconception that the analysis phase of waterfall completes the design and the rest of the process is just non-creative execution of programming skills.
- Steven Gordon

Programming

First, solve the problem. Then, write the code.
- John Johnson

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.
- Bill Gates

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
- Donald Knuth

As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.
- Maurice Wilkes discovers debugging, 1949

Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.
- Henry Spencer

If debugging is the process of removing software bugs, then programming must be the process of putting them in.
- Unknown author

General

For every complex problem there is an answer that is clear, simple, and wrong.
- H L Mencken

Make everything as simple as possible, but not simpler.
- Albert Einstein

Copy and paste is a design error.
- David Parnas

Once a new technology starts rolling, if you're not part of the steamroller, you're part of the road.
- Stewart Brand

There's no sense in being precise when you don't know what you're talking about
- John von Neumann

Anyone who considers arithmetical methods of producing random numbers is, of course, in a state of sin.
- John von Neumann

Good judgement is the result of experience. Experience is the result of bad judgement.
- Fred Brooks

Even if you're on the right track, you'll get run over if you just sit there.
- Will Rogers

"Autorski" komentarz
Część cytatów dotyczy prowadzenia projektów programistycznych, projektowania systemów i fazy zbierania wymagań. Dla czytelnika nabierają większego sensu po lekturze dowolnej książki na temat software engineering i patologii które w SE występują :) Tym bardziej mogę się założyć, że dla osoby z dłuższym stażem w tym biznesie są one bliższe niż dla studenta :)

niedziela, 22 lipca 2007

Wielowątkowość w WinForms

Korzystając z WinForms wcześniej czy później możemy mieć problem z odwołaniem się do kontrolek z innego wątku - stworzonego np w celu zabezpieczenia GUI przed zawieszeniem podczas wywołania metod, które długo działają. Bezpośrednie wywołanie metod kontrolki z innego wątku spowoduje wystąpienie wyjątku InvalidOperationException z komunikatem "Cross-thread operation not valid: Control 'xyz' accessed from a thread other than the thread it was created on.".

Rozwiązaniem jest skorzystanie z metody Invoke klasy Control w celu wywołania zdarzenia działającego w wątku, w którym działa kontrolka. Rozwiązanie to jest zaprezentowane poniżej.

Klasa z metodą działającą w osobnym wątku (listing A):

class ThreadTest
{
public void Run(object form1)
{
(form1 as Form1).SetText("thread test");
}
}

Standardowe uruchomienie wątku (listing B):

private void button1_Click(object sender, EventArgs e)
{
ThreadTest threadTest = new ThreadTest();

Thread thread = new Thread(
new ParameterizedThreadStart(threadTest.Run));
thread.Start(this);
}

Metoda wywoływana z osobnego wątku (listing C):

public void SetText(string text)
{
if (this.InvokeRequired)
this.Invoke(SetTextEvent, new object[] { text });
else
{
textBox1.Text = text;
}
}

Property InvokeRequired służy do sprawdzenia, czy wywołanie metody pochodzi z tego samego wątku co wątek kontrolki. Natomiast metoda Invoke() wywołuje delegata, ale nie w wątku aktualnym, tylko w wątku należącym do kontrolki.

Dla pełnego kodu jeszcze pokaże konstruktor formy (listing D):

private delegate void DelegateWithString(string s);
private event DelegateWithString SetTextEvent;

public Form1()
{
InitializeComponent();

SetTextEvent += SetText;
}

W konstruktorze nastąpiło przypisanie metody do zdarzenia, które będzie wywołane w wątku kontrolki.

UPDATE 2008.12.04:
Powyższa metoda jest poprawna, ALE wymaga pisania nadmiarowego kodu do obsługi event'a. Od .NET'a 2.0 jest na to lepszy sposób - metody anonimowe :)
Wykorzystując wspomnianą wyżej technikę można całkowicie zrezygnować z listingu D, a listing C przepisać następująco:

public void SetText(string text)
{
if (this.InvokeRequired)
this.Invoke((EventHandler)(delegate(object sender, EventArgs e)
{
SetText(text);
}));
else
{
textBox1.Text = text;
}
}


W sumie to powinienem dawno temu updateować tego posta, ale jakoś zapominałem o tym ;)

sobota, 21 lipca 2007

Singleton w C# - cała prawda

Po publikacji posta o "Managerze", miały miejsce pewne dyskusje, że tak powiem, dotyczące wzorca projektowego Singleton - którego jakby nie było używam od co najmniej 5 lat :P

W języku C# istnieje co najmniej pięć sposobów implementacji tego wzorca. Różnią się prostotą implementacji oraz obsługą wielowątkowości. Wszystkie [pięć] opisane są na stronie http://www.yoda.arachsys.com/csharp/singleton.html.
Moja koncepcja najbardziej zbliżona jest do czwartej wersji z tej strony - którą zresztą faworyzuje autor artykułu. Nie uwzględniłem tylko dwóch rzeczy: statycznego pustego konstruktora, który właśnie zabezpiecza "thread safety" tworzenia instancji oraz oznaczenia klasy jako sealed dla bezpieczeństwa i optymalizacji. Od dziś będę już o nich pamiętał ;) Kod poprawnego Singletona w C# to według mnie:

public sealed class Singleton
{
static readonly Singleton instance = new Singleton();

static Singleton()
{
}

private Singleton()
{
}

public static Singleton Instance
{
get
{
return instance;
}
}
}

Piąta koncepcja Singletona, prezentowana na wspomnianej stronie, zabezpiecza tzw. "fully lazy instantiation" - czyli tworzenie instancji dopiero w momencie, gdy referencja do niej jest pobierana przez użytkownika. Uzyskuje się to poprzez klasę wewnętrzną, która tworzy obiekt klasy Singletona. Oto kod (z moimi małymi poprawkami):

public sealed class Singleton
{
private Singleton()
{
}

public static Singleton Instance
{
get
{
return Nested.instance;
}
}

class Nested
{
static Nested()
{
}

internal static readonly Singleton instance = new Singleton();
}
}

Na bezie tej wersji powstał kod Singletona umieszczony na Wikipedii wykorzystujący szablon. Jeden z komentarzy do wcześniejszego post'a o Managerze odnosił się właśnie do tej implementacji ;) IMHO jest to komplikowanie sobie życia, ponieważ jedyne co się zyskuje to wydłużenie nazwy Singletona, której to w końcu ciągle się używa ;) No chyba że ktoś ma z 9 różnych Singletonów ;)

piątek, 20 lipca 2007

Konkursy programistyczne

Jakiś czas temu brałem udział w konkursach programistycznych on-line. Polegały one na rozwiązywaniu zadań algorytmicznych przy pomocy jakiegoś języka programowania. W takich konkursach do systemu wysyła się kod źródłowy programu, system go kompiluje i automatycznie pokazuje czy zadanie jest zaakceptowane.
No chyba nie muszę pisać, że takie konkursy rozwijają pewne pożądane umiejętności, które, według mnie, powinien posiadać każdy zawodowy programista - a nie tylko ci po UW czy UJ :P

Popularne systemy:
- ACM Problem Set - (nowy adres). System na którym spędziłem najwięcej czasu. Jest tam dużo zadań o bardzo zróżnicowanym poziomie trudności, forum i różne statystyki. Polecam.
- Sphere Online Judge - System rozwijany przez studentów Politechniki Gdańskiej, wzorowany na ACM'ie. Nie korzystałem, ale podobno ciekawe zadania, no i polski (ale treść zadań jest po angielsku).
- Top Coder - ciekawy chodź skomplikowany system. Zaletą jest to, że co jakiś czas są organizowane zawody online, w których na rozwiązania zadania ma się określony czas, a zwycięzca dostaje kasę, nawet sporo. Ostatnio także wprowadzono ciekawą funkcjonalność: pisania oprogramowania na zamówienie w formie konkursu, też za kasę :)

Dla osób zainteresowanych przygotowałem parę wskazówek do konkursu ACM. Na początek jak wszyscy, należy zrobić problem nr 100. Jest on prosty, a przy okazji można zobaczyć na czym polega submit'towanie problemu i sprawdzanie poprawności rozwiązania. BTW: zawsze można wysłać jeden problem parę razy, nawet jak się go zaliczyło - można spróbować trochę przyśpieszyć program i być wyżej w rankingu ;). Uwaga: numer zadania nie określa jego trudności.

A więc na początek proponuje następujące zadania:
- najprostsze problemy jakie znalazłem: [100], 272, 113, 591, 458, 102, 10055, 494, 499, 488, 10071, 362;
- a następnie proponuję: 371, 299, 476, 579, 498, 445, 112, 477;
- z takich troszkę trudniejszych: 291, 333, 516, 514, 438, 356, 161, 101, 177.

Jeżeli ktoś szuka akurat hobby, no to ma jak znalazł :P