2011-01-04 8 views
5

"sabit nesneler" örneklerinin devlet değiştirilemez o değişmez anlam sınıflar oluşturma ile kullanılan fabrika benzeri (java) yöntemleri çağırmak için ne; Java'da (ve benzer dillerdeki), kurucuda atanan tüm alanlar), bazen değiştirilmiş örneklerin oluşturulmasına izin vermek bazen yararlıdır. Yani, bir örneği taban olarak kullanmak ve yalnızca bir özellik değerine göre farklılık gösteren yeni bir örnek oluşturmak; baz örneğinden gelen diğer değerler. Yanisabit nesneler

public class Circle { 
    final double x, y; // location 
    final double radius; 

    public Circle(double x, double y, double r) { 
    this.x = x; 
    this.y = y; 
    this.r = r; 
    } 

    // method for creating a new instance, moved in x-axis by specified amount 
    public Circle withOffset(double deltaX) { 
    return new Circle(x+deltaX, y, radius); 
    } 
} 

: Basit bir örnek vermek gerekirse, bir benzeri sınıfı olabilir "withOffset" yöntemi ne denir edilmelidir? (not: isminin ne olması gerektiği DEĞİL - ama bu yöntemlerin adı ne denir?). Teknik olarak, bu bir tür fabrika yöntemidir, ancak bir şekilde bana pek de doğru görünmüyor, zira fabrikalar genellikle basit özellikler (ve ya statik yöntemler, ya da sonuç türünün üyeleri değil, fabrika tipi) olarak veriliyor. Bu yüzden orada tahmin ediyorum

tür yöntemler için daha iyi bir terim olmalıdır. Bu yöntemler " fluent interface" uygulamak için kullanılabilir, belki "akıcı fabrika yöntemleri" olabilir? Daha iyi öneri?

DÜZENLEME: Yanıtlardan biri tarafından önerilen şekilde, java.math.BigDecimal, 'add', 'subtract' (etc) yöntemleri ile iyi bir örnektir.

Ayrıca: Ben

EDIT (o yöntemi için ilgili özel isim sorar rağmen) bir çeşit ilgili olduğunu (az Jon Skeet tarafından) this question var olduğunu fark MAYIS-2014: Benim şu anki favori mutant factory FWIW olduğunu .

+0

Kötü adlandırılmış bir yöntem olarak adlandırıyorum. – Falmarri

+0

"move" ve "delta", varolan bir örneğin özelliklerinin mutabilitesine işaret eder ... – BoltClock

+0

Lütfen asıl soruları okuyun - Yöntemleri nasıl adlandıracağımı sormadım, fakat yöntemlerin nasıl çağrılacağını sormadım. Ama sadece başkalarının kenarda durmasını önlemek için kodu biraz değiştireceğim. – StaxMan

cevap

3

Bu tür yöntemler "kopyalama yöntemleri" yöntemlerini arıyorum. clone() yöntem tam bir kopyasını oluşturur iken

bir kopya yöntemi genellikle bir zımni veya açık varyasyon, bir örneğinin bir kopyasını oluşturur. Örneğin, String#toUpperCase(), immutable String sınıfının bir kopyalama metodu olacaktır - bir varyasyonu bir örneklemle kopyalar: tüm harfleri içerir.

Örneğinizde benzer bir kopyalama yöntemi olarak withOffset() yöntemini düşünürüm.

"Kopyalama yöntemi" terimini belgeleyen başvuruları bilmiyorum. "Kopya" terimini C++ 'daki kullanımından ödünç alıyorum: kopya yapıcılar ve "kopya" adlandırma kılavuzunu Taligent Kodlama Standartları'ndan (more info). Bir "akıcı arayüz" sadece bir API stili (oluşturucu desen ayrı) olduğu teriminin "akıcı fabrika yöntemleri" gelince


, ben, neden "akıcı" bir fark yaratacağını bilmiyorum. "Fabrika metodu" terimi burada geçerli değilse, "akıcı bir fabrika metodu" olarak adlandırmanın daha iyi uygulanmasını nasıl sağladığını göremiyorum.

+0

Akıcı bölüm, akıcı tarzını desteklemek için sıklıkla kullanılan yöntemlere dayanan bir öneriydi. Bununla birlikte, akıcı tarzın değişmezlikle aynı olmadığını (veya zorunlu olarak teşvik ettiğini) aynı değildir. "kopyalama yöntemi" mantıklı geliyor, daha iyi önerilerde bulunup bulunmadığını görelim. (Ben aslında "kopya yapıcıyı" söz konusu referans olarak belirtmek üzereydim, ancak olası karışıklığı ortadan kaldırmaya karar verdim) – StaxMan

1

Bu gerçekten bir fabrika yöntemine benzemiyor. imza yalnız sadece ben ama yeni bir örneğini oluşturmak gerekiyordu değil, farklı çağrılarında bunu zincir bildirirse:. Daha ekler sağlayan bir StringBuilder ("a") gibi bu kullanım şeklini bkz (ekleme) "b". Her seferinde yeni bir StringBuilder'ı (Circle'ınızın yaptığı gibi) döndürür.

Yani tasarım gereği bir fabrika değil. (Arayüzü çıkarmayı ve bu yöntem için JavaDoc'u yazmayı düşünün: "değişmez olduğum için yeni bir örnek döndürmeli" - neden böyle?) Sınıfınızın değişmez olduğu gerçeği sadece bir uygulama detayıdır).

DÜZENLEME: bu da değişmez beri Perahs daha iyi bir örnek, BigInteger olurdu. yeni bir örneğini döndürür ve çok iyi duruma benzeyen

BigInteger multiply(long v) 

: multiply (BigInteger) ile birlikte, bir paket-özel yöntem sağlar. Bu basitçe, başlangıç ​​nesnesiyle aynı türden bir sonucu döndüren bir işlemdir; bir fabrika değil ve bu tarz bir işlemin kendi adını gerçekten hak ettiğini düşünmüyorum.

+0

Bunun bir fabrika yöntemi olmadığını kabul ediyorum Bu yüzden daha iyi bir dönem bulmayı umuyordum. BigInteger iyi bir örnek. Fakat bunun ötesinde, değişmezliğin burada çok önemli bir nokta olduğunu unutmayın; ve kesinlikle bir uygulama detayı (sadece) değil, tüm nesne sadece bu yöntemle değil, değişmez olmalıdır. Belki de değişmez nesne stili veya faydaları ile aşina değil misiniz? Çok iş parçacıklı ve eşzamanlı veri yapıları ile muazzam bir şekilde yardımcı olur. StringBuilder ile, örneğin döndürme, zincirlemeyi sağlayan bir kolaylıktır. – StaxMan

+0

Hiçbir zaman yöntemin değişmez olduğunu, değişmezliğin İletimdeki Circle sınıfının nesnelerine başvurduğunu söylemedim. "Implementatin detail" dedim çünkü bu yöntemi sınıflandırmak ve gerçek uygulamayı görmezden gelmek için sadece bu yönteme bakmaya çalışıyorum. Demek istediğim, bunun soyut bir yöntem olsaydı (bir arayüzde bildirilmişti), bu gibi davranmak için _all_ uygulamalarının gerekmesi ihtimal dışıdır. Bu nedenle, bu davranışın bu yöntem için gerekli olmadığını düşünüyorum. –

+0

Daha iyi bir örnek buldum düşünüyorum: String.concat() - Bu CharSequence arabiriminden gelmiyor olsa da. Javadoc diyor ki: "Bağımsız değişken dizesinin uzunluğu 0 ise, bu String nesnesi döndürülür". X ofsetin 0 olması durumunda da aynısını yapabilirsiniz, böylece yeni bir nesne bile bir gereklilik değildir. –

3

Hmm ... belki biz bir mutant fabrika bitirmeliyiz ... nesnenin mutasyona uğramış sürümlerini oluşturur? :-)

+0

Hehe, Bunu sevdim. :) – StaxMan