2012-04-30 18 views
5

"Tell, don't Ask"-principle'u takiben, bir kişi OOP'taki alıcıları kullanmamalıdır.OOP - GET/SET olmadan

Ama (en azından öyle düşünüyorum) sorunların nasıl çözüleceği, bir nesneden gerçekten "içeriden bilgi" ye gereksinim duyuyor? Yani aşağıdaki örnek nasıl değiştirilir, böylece create_bill() işlevi her bir öğenin fiyatı için sormaya gerek duymaz?

class chopping_cart { 

    private $itemlist = array(); 

    function item_add($name, $price) { 
     $his->itemlist[]=new item($name, $price); 
    } 
    private create_bill() { 

     foreach $this->itemlist AS $element; 
     $sum += $element->get_price(); 

    } 
} 


class item { 
    private $name; 
    private $price; 
    function __construcor($name,$price) {...} 
    function get_price() { 
     return $price; 
    } 
} 

Kullanımı:

$sc = new shopping_cart() 
$sc->item_add("Bike", 1.00); 
$sc->item_add("Ship", 2.00); 
$sc->create_bill(); 
+0

, alışveriş sepetinin her bir öğenin fiyatının değerini öğrenmesini sağlamak neden kötüdür? – user12345613

+1

belirtilen "Tell Don't Ask" ifadesini izleyerek kötülük gibi görünüyor. – Tom

+0

Bu "söyleme" ilkesini nereden duydunuz? Bunu hiç duymamıştım. – xxpor

cevap

7

hiç alıcılar kullanarak yanlış bir şey varsa sen, ben sanmıyorum Bahsettiğiniz nesneyi değiştirmek için istenen veri/eyalet kullanmıyorsanız .

Böyle bir senaryo hakkında prensip görüşmeler:

$item->set_minimum_price(5) gibi bir şey dönüştü edilmelidir
if ($item->get_price() < 5) { 
    $item->set_price(5); 
} 

.

4

o ayı yakın muayene bahsediyorsan "Tell, Don't Ask" makaleden iki öğe vardır:

  1. [...] sormayın [nesneler] onların durumu hakkında sorular, bir karar ve sonra onlara ne yapmaları gerektiğini söyleyin.
    Örneğinizle, chopping_cart yalnızca & nesnelerini sorgular. Önemli olarak, onlara ne yapmaları gerektiğini anlatmaya devam etmiyor.
  2. Tasarım gereği Sözleşmeye göre, yöntemleriniz (sorgular ve komutlar) serbestçe karıştırılabilir ve bunu yaparak sınıf değişmezini ihlal etmenin bir yolu yoktur, o zaman sorun yoktur. Ancak, sınıf değişmezini sürdürürken, ne kadar devletin maruz kaldığına bağlı olarak arayan ve aranan arasındaki bağlantıyı da önemli ölçüde artırmış olabilirsiniz.
    Getirici çağrılar genellikle serbestçe karıştırılabilir, dolayısıyla sınıf değişmezlerini koruma ihtiyacından kaynaklanan hiçbir eşleşme yoktur.

Böylelikle, alıcılar "söyleme, sorma" ilkesinin önlenmesi gereken sorunlara neden olmaz.

2

Bu durumda Visitor design pattern'u kullanabilirsiniz. Product sınıfınızda addToBill yöntemini uygulayın ve argüman olarak, fatura arayüzünüzü uygulayan bir örneği iletin, IBill. IBill, öğede mevcut olan tüm gerekli bilgileri kabul edecek bir addToTotal yöntemini destekler; senin durumunda, bu bir bedeldir. Örneğin, her zaman titrek bir zemin oluşturacaksınız. Yukarıdaki, bir değişkeni (toplam tutar, satır öğesi fiyatlarının ve miktarlarının toplamı ile eşleşmelidir) tanıtan bir addToTotal gibi bir yöntemi gerektirir, sadece "Tell, Don't Ask" un kaçınması gereken bir şey. addToTotal: olmadan yapmayı deneyebilirsiniz * Uzakta Bill; ShoppingCart toplamı takip ediyor. & ürün miktarına ek olarak fiyatı addItem'a iletin; addItem toplamı günceller. Bu, bir çok şey için LineItem veya Product kullanmadığınız için sınıflara sahip olmanın amacını bozar.Bu aynı zamanda, ürünün oluşturulduğunda verilen fiyatın ve verilen fiyatın eşleşmesi gerekse de, sorunlara neden olmamalıdır (sadece garip olur). * addItem, Product ve LineItem; addItem toplamı günceller. Daha önce eklenmiş olan ek öğeler eklendiğinde, $price numaralı iletinin geçmiş aramalarda geçen tutarla eşleşmesi veya addItem'un ek olarak varolan öğeleri ekleyebilmesi için ek bir değişmez olması gerekir. * Eşyaların hepsini bir arada yapın. ShoppingCart, ürün kimliğini ve miktarını depolar. addItem numaralı her çağrı, toplamı günceller. createBill önceden hesaplanmış toplamı kullanır. Diğerlerinden bile daha fazla, bu separate concerns birleştirir.

Başka potansiyel tasarımlar vardır, ancak her biri tipik olarak endişelerin ayrılması, invaryantların tanıtılması ve karmaşıklık eklenmesiyle ilgili bir tür sorundan muzdariptir. Hepsi bir arada, bir satır öğesinin toplam ücretine, doğrudan toplamı hesaplayan yöntemle erişilmesi, yalnızca en basit değil, en temiz ve en az hata üretme olasılığıdır. Bir alışveriş sepetinde ürün eşi varsa

İlgili konular