Category Archives: Genel

Genel Yazılım ve Sistem Mühendisliği

Dekoratör Tasarım Deseni

Dekoratör tasarım deseni, bir nesne üzerinde yapısal değişiklik gerçekleştirmeden yeni yetenekler kazandırılmak istenildiği durumlarda tercih edilen bir tasarım kalıbıdır. Genellikle tekil sorumluluk ilkesi gereği sorumlulukların müferit sınıflar arasında bölünmek istendiği yerlerde tercih edilir. Belirli bir mal veya hizmetin satışında ara toplam, indirimler, vergiler ve özel durumların hesaplanması istendiği durumlar için son derece elverişli bir yapısal tasarım desenidir.

Gerçek Hayat Örneği:

Bir elektronik ticaret sitesinde aşağıdaki kampsamda hizmetler veirlebilmektedir.

* Kullanıcı sepetine istediği kadar ürün ekleyebilir.
* Sabit tutarlı veya yüzdelik cinsten indirimlerden yararlanabilir.

İstisnalar:

* Kullanıcı A kategorisindeki aynı üründen 3 adet satın alırsa 2 tanesinin parasını öder.

Problem:

Kullanıcı yeni yıl kategorisinden 3 adet gömlek satın almış, hesabına tanımlı olan 10 TL lik indirimden yararlanmıştır.

Uygulama:

Başlamadan önce sepet, ürün ve indirim sınıflarımızı tanımlayalım.

namespace Basket;

class BasketItem
{
	/**
	 * @var string
	 */
	private $code;

	/**
	 * @var Category;
	 */
	private $category;

	/**
	 * @var string
	 */
	private $name;

	/**
	 * @var float
	 */
	private $price;

	public function BasketItem($code, $category, $name, $price)
	{
		$this->code = $code;
		$this->cateogry = $categorY;
		$this->name = $name;
		$this->price = $price;
	}

	/**
	 * @return string
	 */
	public function getCode()
	{
		return $this->code;
	}

	/**
	 * @return Category
	 */
	public function getCategory()
	{
		return $this->category;
	}

	/**
	 * @return string
	 */
	public function getName()
	{
		return $this->name;
	}

	/**
	 * @return float
	 */
	public function getPrice()
	{
		return $this->price;
	}
}
<?php
namespace Basket;

use Basket\BasketItem;
use Promotion\Discount;

class Basket
{
	/**
	 * @var SplObjectStorage
	 */
	private $collection;

	/**
	 * @var float
	 */
	private $totalPrice = 0.0;

	/**
	 * @var \Promotion\Discount
	 */
	private $discount;

	public function Basket()
	{
		$this->collection = new SplObjectStorage();
	}

	/**
	 * @return SplObjectStorage
	 */
	public function getItems()
	{
		return $this->collection;
	}

	/**
	 * @param BasketItem $item
	 * @return Basket
	 */
	public function add(BasketItem $item)
	{
		$this->collection->attach($item);
		return $this;
	}
	
	//...

	public function getTotalPrice()
	{
		return $this->totalPrice;
	}

	public function setTotalPrice($value)
	{
		$this->totalPrice = $value;
	}

	/**
	 * @return \Promotion\Discount
	 */
	public function getDiscount()
	{
		return $this->discount;
	}

	/**
	 * @param \Promotion\Discount $discount
	 */
	public function setDiscount(Discount $discount)
	{
		$this->discount = $value;
	}

	//...
}
<?php
namespace Promotion;

class Discount
{
	DISCOUNT_TYPE_FIXED = 'fixed';
	DISCOUNT_TYPE_PERCENTAGE = 'percentage';

	/**
	 * @var string
	 */
	private $type;
	
	/**
	 * @var float
	 */
	private $amount;

	public function Discount($type, $amount)
	{
		$this->type = $type;
		$this->amount = $amount;
	}

	/**
	 * @return string
	 */	
	public function getType()
	{
		return $this->type;
	}

	/**
	 * @return float
	 */
	public function getAmount()
	{
		return $this->amount;
	}
}

Hesaplama işlemi sırasında kullanıcının sepetini dekore edeceğimize göre sepet ve somut dekoratör sınıfları benzer niteliklere sahip olmalıdır. Bunun için sepet ve dekoratör sınıflarının implement edeceği arayüz sınıfını oluşturalım.

<?php
namespace Calculator;

interface Calculatable
{
	public function getTotalPrice();
}

* Sepet nesnesinin yeni oluşturduğumuz arayüzü implement etmesini sağlıyoruz.

<?php
namespace Basket;

use Basket\BasketItem;
use Calculator\Calculatable;

class Basket implements Calculatable
{
	//...
}

Her dekoratör, kurulum sırasında sepeti veya bir başka dekoratörü argüman olarak alabilir. Birden fazla somut dekoratör sınıfım olacağını varsayarak yeni bir soyut dekoratör sınıfı oluşturuyorum.

<?php
namespace Calculator\Calculator;

use Calculator\Calculatable;

abstract class CalculatorAbstract implements Calculatable
{
	/**
	 * @var Calculatable
	 */
	protected $decoratedObject;

	/**
	 * @var Calculatable $decoratedObject
	 */
	public function CalculatorAbstract(Calculatable $decoratedObject)
	{
		$this->decoratedObject = $decoratedObject;
	}

	public function getItems()
	{
		return $this->decoratedObject->getItems();
	}

	public function getTotalPrice()
	{
		return $this->decoratedObject->getTotalPrice();
	}
}

* Sepet toplamını hesaplayacak yeni bir dekoratör sınıfı oluşturuyorum.

<?php
namespace Calculator\Calculator;

use Calculator\Calculator\CalculatorAbstract;

class TotalPriceCalculator extends CalculatorAbstract
{
	public function getTotalPrice()
	{
		$total = 0;
		foreach($this->decoratedObject->getItems() as $item) {
			$total += $item->getPrice();
		}
		return $toal;
	}
}

* Aynı kategorideki bir üründen 3 adet satın alındığında 2 ürün parası ödemeyi sağlayacak decoratörü geliştirelim.

<?php
namespace Calculator\Calculator;

use Calculator\Calculator\CalculatorAbstract;

class SpecialOfferCalculator extends CalculatorAbstract
{
	const OFFER_LIMIT = 3;

	public function getTotalPrice()
	{
		$totalPrice = $this->decoratedObject->getTotalPrice();
		$groupedProducts = array();

		$isDiscountApplied = false;

		foreach($this->decoratedObject->getItems() as $item) {
			$categoryId = $item->getCategory()->getId();
			
			if(!array_key_exists($groupedProducts, $categoryId)) {
				$groupedProducts[$categoryId] = array();
			}
			
			$groupedProducts[$categoryId][] = $item;

			if(count(groupedProducts[$categoryId]) >= self::OFFER_LIMIT and !$isDiscountApplied) {
				$totalPrice -= $item->getPrice();
				$isDiscountApplied = true;
			}
		}

		return $totalPrice;
	}
}

Yazının başında kullanıcıların, indirimleri yüzde veya sabit tutar cinsinden kullanabileceğinden söz etmiştik. Ancak soyut düşündüğümüzde indirim hesaplamak bizim için nihayi rakama ulaşmaktaki adımlardan biri olup, indirimin yüzde veya sabit tutar cinsinden olması ise indirimin hesaplama metodolojisidir. Bu nedenle indirim hesaplama yöntemini sepet hesaplayıcılardan soyutlamak için strateji tasarım desenini kullanarak yeni bir indirim hesaplayıcı sınıf ailesi oluşturacağız.

<?php
namespace Promotion\Discount;

interface DiscountType
{
	/**
	 * @param float $discountAmount
	 * @param float $price
	 */
	public function calculate($discountAmount, $price);
}
<?php
namespace Promotion\Discount;

use Promotion\Discount\DiscountType;

class FixedDiscount implements DiscountType
{
	/**
	 * @param float $discountAmount
	 * @param float $price
	 */
	public function calculate($discountAmount, $price)
	{
		return $price - $discountAmount;
	}
}
<?php
namespace Promotion\Discount;

use Promotion\Discount\DiscountType;

class PercentageDiscount implements DiscountType
{
	/**
	 * @param float $discountAmount
	 * @param float $price
	 */
	public function calculate($discountAmount, $price)
	{
		return $price - ($price * ($discountAmount / 100));
	}
}
<?php
namespace Promotion;

use Promotion\Discount\DiscountType;

class DiscountContext
{
	/**
	 * @var \Promotion\Discount\DiscountType
	 */
	private $discountType;

	public function DiscountContext(DiscountType $discountType)
	{
		$this->discountType = $discountType;
	}

	public function apply($discountAmount, $price)
	{
		return $this->discountType->calculate($discountAmount, $price);
	}
}

* Şimdi de İndirim tutarını sepet toplamına yansıtacak dekoratör sınıfımızı oluşturalım.

namespace Calculator\Calculator;

use Promotion\Discount;
use Promotion\DiscountContext;

class DiscountCalculator extends CalculatorAbstract
{
	public function getTotalPrice()
	{
		$discount = $this->decoratedObject->getDiscount();
		if($discount->getType() == Discount::DISCOUNT_TYPE_FIXED) {
			$discountType = new \Promotion\Discount\FixedDiscount();
		} elseif($discount->getType() == Discount::DISCOUNT_TYPE_PERCENTAGE) {
			$discountType = new \Promotion\Discount\PercentageDiscount();
		} else {
			throw new Exception('Bad discount defination.');
		}
		$context = new DiscountContext($discountType);
		return = $context->apply($discount->getAmount(), $this->decoratedObject->getTotalPrice());
	}
}

Artık sepet tutarımızı hesaplamaya hazırız.

<?php
namespace MyApp;

use Basket\Basket;
use Basket\BasketItem;
use Promotion\Discount;
use Calculator\Calculator\TotalPriceCalculator;
use Calculator\Calculator\SpecialOfferCalculator;
use Calculator\Calculator\DiscountCalculator;

class Main
{
	public function main()
	{
		$basket = new Basket();
		$basket->add(new BasketItem("001", new Category(1, 'Giyim'), 'Gömlek', 80))
			->add(new BasketItem("001", new Category(1, 'Giyim'), 'Gömlek', 80))
			->add(new BasketItem("001", new Category(1, 'Giyim'), 'Gömlek', 80))
			->add(new BasketItem("002", new Category(1, 'Giyim'), 'Pantolon', 200));
		$basket->setDiscount(new Discount(Discount::DISCOUNT_TYPE_FIXED, 10));
		$basket = new DiscountCalculator(new SpecialOfferCalculator(new TotalPriceCalculator($basket)));
		print $basket->getTotalPrice(); //TotalPrice = 350 TL
	}
}

Genel

10 Kasım


Mustafa-Kemal-Atatürk-37
Ulu önderimiz Mustafa Kemal Atatürk’ü saygı ve rahmetle anıyoruz.

Genel Sürüm Yönetimi

GIT Tricks

Gün içerisinde sıklıkla kullandığım ufak GIT numaralarını sizlerle paylaşmak istedim.

Commit tarihçesini ağaç yapısı halinde göstermek için:

$ git log --graph --decorate --pretty=oneline --abbrev-commit

log: Commit tarihçesini görüntülemek için kullanılır.
–graph: Commit tarihcesinin ağaç yapısı şeklinde görselleştirilmesini sağlar.
–decorate: Dalların birleşme/ayrılma noktaların dal isimlerinni çıktıda görüntüler.
–pretty=oneline: Çıktıdaki her bir commit için tek bir satır görüntülenmesini sağlar.
–abbrev-commit: Commit hash inin 6 karakterden oluşan kısa formatıyla gösterilmesini sağlar.

Beliri bir commit aralığındaki logları görüntülemek için:

$ git log <baslangic_commit_hash>..<bitis_commit_hash>

log: Commit tarihçesini görüntülemek için kullanılır.
ref1…ref2 ref1/ref2, tag, dal veya commit gibi belirli bir GIT referansını temsil eder. Aralık alınacağı bilgisi referanslar arasına eklenen ‘..’ ile belirtilir.

Bir dalın, hangi commit den çıktığını görüntülemek için

$ git merge-base <base_branch> <[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>

merge-base: Belirli bir dalın taban daldan ayrılma noktasını belirlemek için kullanılır.

Bir git dalının çıktığı noktadan itibaren gerçekleştirilen değişikliklerin listesini almak için:

$ git log $(git merge-base <base_branch> <[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]> )..<[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>

Belirli bir commit aralığıında değişen dosyaların listesini görmek için

$ git diff --name-only <[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>..<[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>

diff: Belirli bir aralıkta meydana gelen değişiklikler ile ilgili bilgi sağlar.
–name-only: Çıktıda yalnızca dosya ismi görüntülenmesini sağlar.

Belirli bir commit aralığında değişen dosyaların listesini commit bazında görüntülemek için:

$ git log --name-only <[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>..<[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>

log: Commit tarihçesini görüntülemek için kullanılır.
–name-only: Her bir commit için çıktıda yalnızca dosya ismi görüntülenmesini sağlar.

Birden fazla dalın merge edildiği bir dalda, yalnızca o dala ait commitleri görüntülemek için:

$ git rev-list --first-parent <[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>

Yalnız commit hash listesini almak için:

$ git log --abbrev-commit --pretty=format:%h

log: Commit tarihçesini görüntülemek için kullanılır.
–abbrev-commit: çıktıda kısa commit hash lerinin listelenmesini sağlar.
–pretty=format:%h: Çıktıda yalnızca commit hash lerinin yeralmasını sağlar.

Belirli bir commit aralığında, commit tarihcesini tersten almak için:

$ git log --pretty=format:%h --reverse <[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>..<[branch_adi] | [commit_hash] | [ref_adi] | [HEAD]>

log: Commit tarihçesini görüntülemek için kullanılır.
–abbrev-commit: çıktıda kısa commit hash lerinin listelenmesini sağlar.
–pretty=format:%h: Çıktıda yalnızca commit hash lerinin yeralmasını sağlar.
–reverse: Commit tarihçesinin en eskiden en yeniye sıralanmasını sağlar.

Commit mesajı yazılmamış bir commit in hangi dalda geçtiğini bulmak için:

$ git branch -a --contains <commit_hash>

Belirli bir HEAD commit in hangi dala ait olduğunu öğrenmek için:

$ git rev-parse --abbrev-ref <commit_hash>
Genel

Yönetici Halleri

Bugün de birçoğumuzun çeşitli dönemlerde maruz kaldığı yönetici hallerine değinmek istedik. İçinde sizin dışınızda herşeyin yeraldığı bütçeler, genişleyen ekipler, artan cirolar, yeni projeler… Aklıma gelen, çevreden duyduğum ve buradan paylaşabildiğim çeşitli söylemleri 5 farklı grupta topladım:l2

Şirketin hissedarıymışsınızcasına yapılan motivasyon odaklı söylemler:
* İşler büyüyor, çok güzel projeler yapacağız.
* İşler büyüyor, sayımız artıyor, daha sonra kendi takımını kurarsın.
* Yapacak çok işimiz var, ekip büyüor, sayımız artıyor.
* Ekip büyüor, 2 eleman daha alacağız.

Söz nakde gelince Esnaf_Mod=True olan yönetici deyişleri:
* İlk girişte bu şekilde olsun, 3 ay sonra iyileştirme yaparız.
* Şu elimizdeki işleri bitirelim, mart-nisan gibi bir ayarlama yapacağız.
* Zam dönemi gelmeden zaten birebir görüşmelerle sizleri bilgilendiriyor olacağız.
* Şimdi… Arkadaşlar! Biz zam oranlarını % 10x olarak belirledik ama yukarıdan bir takım kesintiler oldu. Nihayi rakam %2.5x

LPG güdümlü iş çıkardığınızı düşünen yönetici deyişleri:
* Performansından çok memnunuz, takımın çok iyi çalışıyor, gerekeni yapacağız.
* Bütün falanca ekibinin sorumluluğunu da sana veriyor olacğaız, tabi ki mevcut görevine de devam edeceksin ancak filanca ekibine de destek olmanı bekliyoruz.
* Bu konuyla özellikle senin ilgilenmeni rica ediyorum.

Bağlama çeken yönetici deyişleri:
* Arkadaşlar biliyoruz kaliteli kod yazmak istiyorsunuz fakat şu elimizdeki işleri tamamladıktan sorna refactoring için sizlere zaman tanıyacağız.
* Sen şimdi bir süre bu ekipte devam et, biz daha sonra senin pozisyonunu ayarlayacağız.

Umursamaz yönetici söylemleri:
* Evet bu önemli bir konu ama 1-2 dakika içinde bir toplantıya katılmam lazım.
* Siz aranızda organize olun, halledin.

Kariyer değişimi ile gelen edit:

Kazın ayağı öyle değilmiş. Bazen iş yürüsün diye istemediğimiz şekilde davranılabiliniyormuş.

Genel

Neşet Ertaş’ı Özlemle Anıyoruz

Yıllar, yıllar önce büyük hayranlıkla dinlediğim Selda Bağcan, Barış Manço ve daha nice yorumcuların seslendirdiği eserlerin altında gördüğüm imzası ve yaptığı bunca güzel işe rağmen eksilmeyen alçak gönüllülüğüyle kendisine olan hayranlığım katlanarak büyüdü. Mekanın cennet olsun.


Büyük ustayı saygıyla anıyoruz

Genel

Doğru GIT Kullanımı ve Birlikte Çalışma Kültürü

Uzun bir aradan sonra tekrar merhaba.

Dağıtık yapısı ve zengin komut setiyle GIT hakikaten geliştiricinin hayatını kolaylaştıran mükemmel bir versiyon kontrol aracı. Ancak temel komut setinin yeteri kadar anlaşılamaması ve birlikte çalışma kültürünün tam anlamıyla yerleşememesi projede zaman zaman kod kayıplarına varan sonuçlara neden olabilmektedir.

GIT kullanımı ile ilgili problemleri genel olarak aşağıdaki gibi gruplayabiliriz:

* Komut setinin yeterince anlaşılamaması.
* Hatalı sürüm hazırlama stratejisi.
* Birlikte çalışma kültüründen kaynaklanan problemler

Komut Setinin Yeterince Anlaşılamaması:

Günlük hayatta kullandığımız temel git komutları olan, fetch, merge, rebase ve pull komutlarının tam olarak ne yaptığının anlaşılamamasıyla başlayan bu problem, geliştirme yapılan dallarda hatalı kullanım nedeniyle meydana gelen sapmalar ve hatta zaman zaman ciddi çakışmalar sonrasında oluşabilecek kod kayıplarıyla sonuçlanabilmektedir.

Dilerseniz öncelikle bu dört komutun tam olarak ne yaptığını özetleyelim.

git fetch:

Uzak depoda oluşturulan nesneleri (commit, tag vs.) yerel geliştirme ortamına transfer eder. Ancak yapılan değişiklikleri projeye yansıtmaz. Aslında kabaca sadece referans bilgilerini aktarır şeklinde düşünebiliriz. Bu işlem sonrasında merge veya rebase komutlarını çalıştıranadek git log branchA veya git diff origin/branchA branchA çalıştırarak uzak ve yerel depolar arasındaki farklılıkları görebilirsiniz.

git merge:

fetch komutu ile uzak depodan aktarılan değişiklikleri, kronolojik sıraya göre (zamana sırasına göre) projeyle birleştirir.

merge komutu çalıştırılmadan önceki durum:

	 branchA

      F    G     H
      o----o-----o
     /
o---o---o----o-----o---
A   B   C    D     E

master

merge komutu çalıştırılmadan sonraki durum:

o---o-o--o--o--o--o--o---
A   B F  C  G  D  H  E
merge edilen dal (master veya branchA)

git rebase:

fetch komutu ile uzak depodan aktarılan değişiklikler, yerel depodaki projeyle birleştirmeden önce ilgili dalın, ana daldan ayrıldığı noktadan itibaren yapılan değişiklikler bir kenarda tutularak dal, rebase edilen dal ile aynı seviyeye getirildikten sonra kenara alınan değişiklikler uygulanır. Böylece ana dalın taban daldan ayrıldığı noktadan itibaren gerçekleştirilen değişiklikler dalın en tepesine taşınır.

rebase komutu çalıştırılmadan önceki durum:

	 branchA

      F    G     H
      o----o-----o
     /
o---o---o----o-----o---
A   B   C    D     E

master

rebase komutu çalıştırılmadan sonraki durum:

	 branchA

                     F    G     H
                     o----o-----o
                    /
o---o---o----o-----o---
A   B   C    D     E

master

git pull:

Bu komut aslında GIT in geliştiricilere sağladığı bir kısayoldur. SVN kullanıcıları hatırlayacaktır. svn update çalıştırıldığında uzak repodaki değişiklikler olduğu gibi alınıp projeye aktarılırdı. pull komutu ise, fetch ve merge veya rebase komutlarını birlikte kullanabilmek için geliştirilmiş bir kısayoldur.

git pull = git fetch + git merge

git pull –rebase = git fetch + git rebase

Görüldüğü üzere pull komutu sonrasında kullanılan –rebase parametresi, komutun uzakta yapılan değişiklikleri dalla birleştirilmesi ile ilgili stratejiyi değiştirir. pull komutu ile birlikte herhangibir parametre kullanmazsanız uzakta yapılan değişiklikler repodan yerel geliştirme ortamına aktarıldıktan sonra doğrudan kronolojik sıraya göre projeyle birleştirilir. Böylece fetch ve merge komutları bir kerede uygulanmış olur. Ancak –rebase parametresinin eklenmesi durumunda GIT birleştirme stratejisi için rebase komutunu uygular.

Hatalı Sürüm Hazırlama Stratejisi

GIT ile ilgili değişik dallandırma ve sürümleme stratejileri mevcut. Aşağıdaki dökümanları inceleyerek sizin için en uygun olan bir model üzerinden devam edebilirsiniz.

A successful Git branching model
GIT: Comparing Workflows

Çok kabaca, projeyi dağıttığınız alfa, beta, pre-prod, … prod gibi birden çok ortam varsa hazırladığınız her sürüm yayına girmeyebilir. Değişen öncelikler, oluşan hatalar veya hataların giderilmesi için harcanan süre nedeniyle sürüme dahil olan paketler sıklıklıkla eklenebilir veya çıkartılabilir. Bu noktada numaralandırılmış release branchleri kullanmak, master dalı temiz tutmak için efektif bir çözüm olabilir. Etiketleme gibi çözümleri de değerlendirebilirsiniz.

Ancak hangi metodolojiyi kullanırsanız kullanın planlanan sürümün oluşturulmasına geçmeden önce mutlaka sürümün oluşturulduğu ortamdaki git repolarını güncelleyin. Aksi durumlarda geliştiricilerden gelen değişikliklerin sürüme yansımaması, oluşan çakışmalar nedeniyle meydana gelebilecek kod kayıpları ve master dalda meydana gelebilecek bozulmalar gibi bir dizi istenmeyen sonuçlarla karşılaşmanız olasıdır.

Aşağıda örnek bir sürüm paketinin hazırlanması ile ilgili akış görülüyor.

* master dalı güncelleyin.

	$ git checkout master 
	$ git pull origin master

* Sürüme girecek dalları rebase ederek master seviyesine getirin.

	$ git checkout ab-001
	...
	$ git rebase origin/master	

	$ git checkout ab-002
	...
	$ git rebase origin/master	

	$ git checkout ab-003
	...
	$ git rebase origin/master	

* Yeni bir sürüm dalı oluşturun.

	$ git checkout -b v1.0.15091301 -t origin/master

* Geliştirmelerin yeraldığı dalları sürüm dalıyla birleştirin.

	$ git merge ab-001 ab-002 ab-003

* Sürümün stabil olduğundan emin olduktan sonra oluşturduğunuz sürüm dalını master dal ile birleştirin.

	$ git checokut master
	$ git merge v1.0.15091301
	$ git push origin master

Eğer sürüm herhangibir problem ihtiva ediyorsa ilgili geliştirme mutlaka hatanın meydana geldiği dalda gerçekleştirilmelidir. Geri dönülebilirliği imkansız hale gelmesi ve yaşanabilecek kayıplar nedeniyle sürüm dalında asla geliştirme gerçekleştirilmemelidir.

Birlikte Çalışma Kültüründen Kaynaklanan Problemler

Geliştirme dalları genellikle master ve release dallarına göre daha sık değişikliğe maruz kalırlar. Özellikle birden fazla kişinin birlike çalıştığı geliştirme dallarında geliştirme ortamının güncel tutulması ve bunun diğer geliştiricileri de düşünerek doğru şekilde yapılması yüksek önem arz eder.

Projeye eklenecek yeni özelliklerle ilgili geliştiricilerin birlikte çalıştığı dallarda, dal hem yerel ortamda hem de uzak depoda sık değişikliklere maruz kaldığından güncellemeler mutlaka geliştirme ortamındaki değişikliklerin sona taşınması suretiyle gerçekleştirilmelidir. Böylece dalda oluşabilecek sapmaların önüne geçilmiş olunur.

Geliştirme ortamınızdaki değişiklikleri tepeye taşımak için git fetch ve git rebase veya git pull –rebase komutlarını kullanabilirsiniz.

Düzgün versiyonlanan bir projede geliştirme yapılan daldaki commit dizilimi, dalın master daldan ayrıldığı noktadan itibaren ip gibi olmalı ve herhangibir sapma meydana gelmemelidir.

Aşağıdaki resimde pull kullanılarak sapma meydana gelmiş bir dalın commit ağacı görülüyor.

Bir sonraki resimde ise pull –rebase kullanılarak güncellenmiş dalın commit ağacı görülüyor.

Sizlerde aşağıdaki komutu kullanarak çalıştığınız daldaki commit dizilimini görüntüleyebilirsiniz. Böylece herhangibir sapma meydana geldiğinde hızlıca müdahale ederek oluşabilecek hasarı ve zaman kaybını minimuma çekmiş olursunuz.

	$ git log --graph --decorate --pretty=oneline --abbrev-commit

Eğer bu ağacı oluşturmak için yukarıdaki uzun komut/parametre dizisini ezberlemek istemiyorsanız aşağıdaki komutu kullanarak lol isimli yeni bir takma ad oluşturabilirsiniz.

	$ git config --global alias.lol "log --graph --decorate --pretty=oneline --abbrev-commit"
Genel

Django Modellerinde ManyToMany Alanların Belirli Bir Filtreye Göre Limitlenmesi

Sistem genelinde taglayabildiğiniz tüm nesne tipleri ile ilgili tag verilerinin tek bir tabloda tutulduğunu düşünelim. Bu durumda tag kayıtlarını bir şekilde sınıflandırmamız ve ilgili nesnelerin sadece kendisiyle ilgili tipteki taglere sahip olabilmesini sağlamalıyız. Bu yapıyı sağlayabilmek için ManyToManyField tanımlaması yapılırken limit_choice_to parametresi kullanılarak ilişkili tablonun neye göre filtreleneceğini dict olarak tanımlamamız gerekir.

Böylece django admin tarafında da kullanıcının ilgili kaydı editlerken manytomany alanda yalnızca kendisiyle ilgili kayıtları görmesi/seçebilmesi sağlanır.

Aşağıda örnek veri modeli yeralıyor.

from django.db import models


class Tag(models.Model):
    TAG_TYPES = (
        ('article', 'Article'),
        ('video', 'Video'),
    )
    slug = models.SlugField(max_length=50)                                     
    name = models.CharField(max_length=50)   
    tag_type = models.CharField(max_length=30)    


class Article(models.Model):
    slug = models.SlugField(max_length=80)
    title = models.CharField(max_length=80)
    content = models.TextField()
    tags = models.ManyToManyField(Tag, limit_choices_to={'tag_type': 'article'})


class Video(models.Model):
    slug = models.SlugField(max_length=50)
    name = models.CharField(max_length=50)
    url = models.UrlField()
    tags = models.ManyToManyField(Tag, limit_choices_to={'tag_type': 'video'})
Genel

PHPKonf İstanbul Konferansı Geliyor…

phpkonf14Evet ve nihayet beklenen etkinlik haberi geldi. İstanbulPHP topluluğu yaklaşık 8 aydır düzenli olarak WebBox sponsorluğunda İstanbul Şehir Üniversitesi’nde organize ettiği aylık buluşmalardan sonra yeni bir PHP Konferansı etkinliği düzenleyeceğini duyurdu. Güvenlilir kaynaklardan edindiğim bilgiye göre etkinliğin multi-track olacağı ve katılımcıları bir yıl boyunca PHP ye doyacak düzeyde içerikle buluşturacakları yönünde duyumlar aldım. Ben de herkes gibi sabırsızlıkla bu etkinliği bekliyorum.

Bu tarz etkinlikler, geliştiricilerin yeni teknolojilerle tanışması, Türkiye’deki geliştirici topluluklarının gelişimi ve dünyaya tanıtımı konusunda önemli rol oynuyor. Dolayısıyla bu bağlamda gerek organizasyon ekibi, gerekse sponsorluk anlamında elini taşın altına koyan herkese buradan kocaman bir teşekkür etmekte yarar var.

Etkinlikle ilgili gelişmelere http://phpkonf.org adresinden ulaşabilirsiniz.

PHPKonf İstanbul etkinliği 25-26 Temmuz’da Bahçeşehir üniversitesinde PHP geliştiricilerini bekliyor.

Bitti mi ? Bitmed. Ben de 25 Temmuz 17:00 deki “Kaya Gibi Sağlam Yazılım Projelerine İmza Atmanın 5 Prensibi” sunumumla karşınızda olacağım.

Genel

Eşyalar toplanmış seninle birlikte…

Ardından anıların odalara saçıldığı, darmadağın günlere bıraktın bizi Tanju Okan.
Ölümünün 19. yılında seni gitgide büyüyen bir özlem ve rahmetle anıyoruz.
Nur içinde yat.

Tanju Okan

Genel

Para Yönelimli Programlama (PYP)

Para Yönelimli Programlama (PYP)Para Yönelimli Programlama, programlama eyleminin para ekseninde gerçekleştirildiği yazılım geliştirme faaliyetidir. Geliştiriciler arasında “Dark Side”, “Para Çokomel”, “Parasıyla değil mi ?” sözleriyle de ifade edilen bu yaklaşımı, bu yazıda birlikte irdeleyeceğiz.

PYP, aslında hepimizin bildiği algülüm vergülüm esasına dayanan ticari bir faaliyetten başka birşey değildir. İşverenin, yazılım geliştirme ihtiyaçlarının karşılanması doğrultusunda aylık periyodlarla yaptığı maaş ödemesine istinaden, geliştiricinin işveren beklentilerini makul sürelerde karşılaması esasına dayanır.

Adından da anlaşılacağı üzere programlama faaliyeti asla mantık ekseninde gerçekleştirilmez. İşin içeriği, yaratacağı prestij kaybı, görsel/mantıksal/fonksiyonel problemler geliştiriciyi ilgilendirmez. Ödemeler düzgün gerçekleştiği sürece müşteri her zaman haklıdır. Ödemenin aksaması, rakip veya farklı sektördeki firmanın yapacağı X+1 lik ücret teklifi mevcut firmayla olan ilişkilerin aynı gün sonlanmasına neden olabilir. (Mevcut firmanın x-1 lik personeli temin edebilmesi durumunda mevcut personelin işine aynı gün sonverebildiği gibi.)

PYP uygulayan geliştiricinin egosu ve fikri olmaz. Şayet fikri varsa ısrarcı olmaz. Tartışmaya girmez. Alınacak nihayi cevap her zaman için “Ok o zaman o şekilde yapalım.” şeklindedir. Kıdeme bağlı olarak “parasıyla değil mi ?” gibi türlü varyasyonların da duyulması mümkündür.

Para Yönelimli Programlama (PYP)Bu tip geliştiriciler, yedi köyle barışık denilecek cinsten insanlardır. Sistemcisinden, proje yöneticisine ve diğer tüm ekip arkadaşlarıyla tam anlamıyla uyum içindedir. Asla laf taşımaz. İşinin yürümesi için herşeyi yapar. Nabza göre şerbet verir. İtin köpeğin önde gidenidir. İş bitiricidir. Üretimin süreci ve sonucu göz önünde bulundurulduğunda aslında her PYP geliştiricisi DGYP ve GGYP yaklaşımlarını da benimser. (Bkz. Daya Geç Yönelimli Programlama (DGYP). Bkz. Goygoy Yönelimli Programlama (GGYP)) Projedeki mevcut özellik defalarca kaldırılıp eklense de asla üşenmez, yorum getirmez. İşverenin kendisine bunun için para ödediğinin bilincindedir.

PYP uygulayan geliştirci, bir projenin öyle veya böyle yayına çıkabilmesi adına her firmada en az birkaç tane bulunması gereken geliştirici tipidir. Ego tatminin yaşanacağı yer işyeri olmadığından işverenin yazılım geliştiricinin egosunun tatmin etmek için iş beğendirmek veya her an yeni bir challange yaratmak gibi bir mecburiyeti yoktur. İşveren para karşılığında geliştiricinin bilgisini ve zamanını satın alır.

Pahalıdır. Standart bir yazılım geliştiriciyi X liraya, bir rockstar ı X+1 liraya çalıştırabilirsiniz. Deneyimli bir PYP geliştiricisini X+2 liraya çalıştıramazsınız. Şayet anlaşsanız bile daha iyi şartları sağlayan başka bir firma bulduğu gün yerinde yeller eser.

Sadakat ancak hayvanlarla insanlar arasında yaşanabilecek bir duygudur. Bu nedenle firmanın geliştiriciden sadakat beklentisi son derece yersizdir. PYP geliştiricisi, yukarıda belirtilen ücret politikası nedeniyle asla herhangibir projede tek adam olarak konumlandırılmamalıdır. Çünkü her an herşey olabilir :)