Aynı adda, ancak farklı ad alanlarına sahip birden fazla sınıf mı?


11

Aynı ada sahip, ancak ad alanlarında farklılık gösteren sınıfları olan bazı kodlar (önemliyse C #) çalıştırdım. Hepsi aynı mantıksal şeyi temsil etme eğilimindedir, ancak genellikle aynı nesnenin farklı "görünümleri" dir. Farklı ad alanları bazen aynı çözümün ve hatta aynı dll'nin bir parçasıdır.

Düşüncelerim var, ancak mevcut araçların akıllıca kullanılması veya kaçınılması için bir desen olarak kabul edilecek bu uygulama hakkında kesin bir şey bulamadım.

Şirin adlandırma ile ilgili bu soru bu konuda dokunuşlar, ancak diğer yönden. İsimleri netleştirmek, muhtemelen bu sorunun ortadan kaldırmak istediği keyfi ve yaygın bir önek gerektirecektir.

Bu uygulamanın etrafındaki yönergeler nelerdir?


1
OOP'ta birçok istisna vardır, ancak ilk başta bu kötü tasarımı düşünürüm, özellikle de tüm sınıflar aynı erişilebilirlik seviyesini paylaşıyorsa. Bir sınıf adını okuduğumda, herhangi bir dosyada, sınıfın hangi ad alanında derhal ad alanı yönergelerine başvurmak zorunda kalmadan bilmek istiyorum.
Leopold Asperger

Aynı durumla ilgili birden fazla ilişkili nesneye sahip olmak için geçerli bir durum vardır, ancak bunlar genellikle işlevle ayrılır. Belki bir modeli görünüme uyarlayan bir nesneniz var. Bir diğeri nesne üzerinde bir hesaplama yapabilir. Başka bir adaptör veya cephe olabilir. Aklınıza gelebilecek Yani FooAdapter, FooViewer, FooCalculatorvb ama kesinlikle aynı şey adlandırılmış değil. Bununla birlikte, konuştuğunuz belirli sınıflar hakkında daha fazla bilgi olmadan, bir cevap vermek zordur.

@JohnGaughan - Employeeörnek olarak düşünün . Biri İK için, diğeri dışarıda maruz kalma için diğer çalışanlar için olan bir çalışan var. Hepsi "işçi" olarak adlandırılır ve hepsinin yardımcıları vardır (EmployeeRepository, EmployeeView, vb.). Hepsi aynı dll'de ve bazı ortak özellikleri (isim, başlık) paylaşırken, hepsi farklı (telefon numarası, maaş).
Telastyn

EmployeeBirkaç kez modellik yapan sistemlerle çalıştıktan sonra , tüm niteliklerin birleşimi ile bir modele ihtiyacınız olduğu ve bir typeveya departmentnitelik içerdiği anlaşılıyor . Aksi takdirde, kodun gereksiz şekilde çoğaltılması söz konusudur.

5
İsim alanlarının başlamasının sebeplerinden biri bu değil miydi? İsim çarpışmalarına izin vermek için?
Dan Pichelman

Yanıtlar:


5

Projelerimden birinde de gördükten ve üzerinde çalıştıktan sonra bu kullanıma karşı bir cevap vermeye çalışacağım.

Kod okunabilirliği

Her şeyden önce, kod okunabilirliğinin önemli olduğunu ve bu uygulamanın buna ters olduğunu düşünün. Birisi bir parça kod okur ve diyelim ki bir işlevi var doSomething(Employee e). Bu artık okunabilir değil, çünkü Employeefarklı paketlerdeki 10 farklı sınıf nedeniyle , girdinizin gerçekte ne olduğunu öğrenmek için önce ithalat beyanına başvurmanız gerekecektir.

Bununla birlikte, bu üst düzey bir görünümdür ve çoğu zaman kimsenin umursamadığı, hatta bulduğu rastgele isim çatışmaları var, çünkü anlamı kalan koddan ve hangi pakette olduğunuzdan türetilebilir. yerel olarak hiçbir sorun yoktur, çünkü Employeebir hrpaketin içinde görürseniz , çalışanın İK görünümünden bahsettiğimizi bilmeniz gerekir.

Bu paketleri terk ettiğiniz anda işler dağılıyor. Farklı bir modül / paket / vb. Çalıştıktan ve bir çalışanla çalışmanız gerektiğinde, türünü tam olarak nitelemiyorsanız okunabilirlikten zaten ödün vermiş olursunuz. Ayrıca, 10 farklı Employeesınıfa sahip olmak, IDE'nizin otomatik tamamlanmasının artık çalışmadığı ve çalışan türünden manuel olarak seçim yapmanız gerektiği anlamına gelir.

Kod çoğaltma

Bu sınıfların her birinin doğası gereği birbiriyle ilişkili olduğundan, çoğaltma nedeniyle kodunuzun bozulması gerekir. Çoğu durumda, her bir sınıfın uygulamak zorunda olduğu bir çalışanın adı veya bir kimlik numarası gibi bir şeye sahip olacaksınız. Her sınıf kendi görüşünü eklese de, temeldeki çalışan verilerini paylaşmazlarsa, o zaman büyük kitleler yararsız, ama pahalı kodlarla karşılaşacaksınız.

Kod karmaşıklığı

Ne sorabilirsiniz ki bu kadar karmaşık olabilir? Sonuçta, sınıfların her biri istediği kadar basit tutabilir. Gerçekten sorun haline gelen şey, değişiklikleri nasıl yaydığınızdır. Oldukça zengin özelliklere sahip bir yazılımda, çalışan verilerini değiştirebilirsiniz - ve bunu her yere yansıtmak isteyebilirsiniz. Bir bayan sadece evli olduğunu söyle ve onu adlandırmak zorunda XiçinYbu nedenle. Bunu her yerde yapmak için yeterince zor, ama tüm bu farklı sınıflara sahip olduğunuzda daha da zor. Diğer tasarım seçeneklerinize bağlı olarak, bu, sınıfların her birinin kendi tür dinleyicisini veya değişikliklerden haberdar edilecek bir şeyi uygulaması gerektiği anlamına gelebilir - bu da temel olarak uğraşmanız gereken sınıf sayısına uygulanan bir faktöre dönüşür . Ve elbette daha fazla kod çoğaltma ve daha az kod okunabilirliği. Bu gibi faktörler karmaşıklık analizinde göz ardı edilebilir, ancak kod tabanınızın boyutuna uygulandığında rahatsız edici.

Kod iletişimi

Tasarım seçenekleriyle de ilgili olan kod karmaşıklığı ile ilgili yukarıdaki sorunların yanı sıra, üst düzey tasarım netliğinizi azaltır ve alan adı uzmanlarıyla düzgün iletişim kurma yeteneğini kaybedersiniz. Mimariyi, tasarımları veya gereksinimleri tartışırken artık basit ifadeler yapmakta özgür değilsiniz given an employee, you can do .... Bir geliştirici artık employeeo noktada gerçekten ne anlama geldiğini bilemeyecek . Her ne kadar bir alan adı uzmanı bunu bilecek olsa da. Hepimiz yapıyoruz. bir çeşit. Ancak yazılım açısından artık iletişim kurmak o kadar kolay değil.

Problemden nasıl kurtulurum

Bunun farkında olma ve sonra eğer ekibiniz mücadele için bir sorun yeterince büyük olduğunu kabul eder, o zaman başa bir şekilde dışarı işe sahip olacaktır. Genellikle, yöneticinizden çöpü çıkarabilmeleri için tüm ekibe bir hafta izin vermesini isteyemezsiniz. Yani özünde, bu sınıfları birer birer kısmen ortadan kaldırmak için bir yol bulmanız gerekecek. Bunun en önemli kısmı - tüm ekiple - Employeegerçekten ne olduğuna karar vermektir . Do not tek tanrı-çalışanın bireysel özelliklerin hepsi entegre. Daha çok çekirdek çalışanı düşünün ve en önemlisi bu Employeesınıfın nerede kalacağına karar verin .

Kod incelemeleri yaparsanız, sorunun en azından daha fazla büyümediğinden emin olmak özellikle kolaydır, yani başka bir tane Employeedaha eklemek istediklerinde herkesi kendi yolunda durdurun . Ayrıca, yeni alt sistemlerin kararlaştırılanlara uymasına Employeeve eski sürümlere erişmesine izin verilmemesine dikkat edin.

Programlama dilinize bağlı olarak, sonunda ortadan kaldırılacak sınıfları, @Deprecatedekibinizin değiştirilmesi gereken bir şeyle çalıştıklarını hemen fark etmelerine yardımcı olmak gibi bir şeyle işaretlemek de isteyebilirsiniz .

Eski çalışan sınıflarından kurtulmak için, her bir vaka için en iyi nasıl ortadan kaldırılacağına karar verebilir veya sadece ortak bir kalıp üzerinde anlaşabilirsiniz. Sınıf adını iliştirebilir ve gerçek çalışanın etrafına sarabilir, desenleri (dekoratör veya adaptör akla gelir) veya veya veya kullanabilirsiniz.

Uzun bir hikaye kısaca anlatmak gerekirse: Bu "uygulama" teknik olarak sağlamdır, ancak yalnızca yolun ilerisinde gerçekleşecek gizli maliyetlerle doludur. Sorundan hemen kurtulamayabilirsiniz, ancak zararlı etkilerini içererek hemen başlayabilirsiniz.


Bir Core sınıfına sahip olmak iyi bir çözüm gibi görünüyor. Diğer sınıflar ondan uzayabilir. IDE hakkında, otomatik tamamlama, hangi sınıfı bağlamla en iyi eşleştirmenizi önereceğinizi bilecek kadar akıllıdır. Genel olarak, özellikle kod tabanı dahili olarak kullanıldığında neden bu kadar büyük bir sorun olduğunu anlamıyorum.
InformedA

1
Bir bağlamın dışında olduğunuzda yeterince akıllı değil. Her iki problemli sınıfa da ihtiyaç duyan bir sınıfı düşünün - otomatik tamamlama hiç yardımcı olmaz. Ve bunları diğer on sınıftan bile ayırmayacak. Ancak asıl sorun, bu paket alanlarının gerçekte ne olduğunu ve hangisini seçmesi gerektiğini bile bilmeyen yeni ekip üyesidir.
Frank

Aynı bağlamda aynı ada sahip birden fazla sınıf kullanılıyorsa, bu zor olur. Ben bu davayı görmedim. Aynı ada sahip birden fazla sınıf gördüm, ancak sıklıkla bahsettiğinizle aynı bağlamda kullanılmıyorlar.
InformedA

@randomA - ne yazık ki, bu durum bu kod tabanında oldukça yaygındır.
Telastyn

İyi noktalar, ancak temel soruna gerçekten bir çözüm vermediniz, ancak çekirdek sorun çözüldükten sonra metodoloji ("bir Çalışan gerçekten ne ise"). Atılan tek "çözüm" ("tüm bireysel nitelikleri bir tanrı çalışanına entegre edin") haklı olarak. DB.Employee, Marshalling.Employee, ViewModels.Employee, GUI.Views.Employee vb. Var, çözümünüz nedir?
Pablo H

9

Scala Koleksiyon Çerçevesi bunun güzel bir örneğidir. Değişken ve değişmez koleksiyonların yanı sıra seri ve paralel (ve gelecekte de dağıtılabilir) koleksiyonlar vardır. Yani, örneğin, dört Mapözellik vardır:

scala.collection.Map
scala.collection.immutable.Map
scala.collection.mutable.Map
scala.collection.concurrent.Map

artı üç ParMaps:

scala.collecion.parallel.ParMap
scala.collecion.parallel.immutable.ParMap
scala.collecion.parallel.mutable.ParMap

Daha da ilginç:

scala.collection.immutable.Map            extends scala.collection.Map
scala.collection.mutable.Map              extends scala.collection.Map
scala.collection.concurrent.Map           extends scala.collection.mutable.Map

scala.collecion.parallel.ParMap           extends scala.collection.Map
scala.collecion.parallel.immutable.ParMap extends scala.collecion.parallel.ParMap
scala.collecion.parallel.mutable.ParMap   extends scala.collecion.parallel.ParMap

Yani, ParMapuzanır ParMapuzanır Mapve Mapuzanır Mapuzanır Map.

Ama yüzleşelim: onlara başka ne diyeceksin? Bu çok mantıklı. İsim alanları bunun için!


3
"İsim alanları bunun için!" => +1
svidgen

Bunu beğendim, ancak C # /. NET dünyasında paralel sınıfları bir Paralel alt ad alanına taşıdığımda, bu daha sonra yardımcı sınıfı System.Threading.Parallel ile çakışarak paralellik elde etmek için kullanıyorum. 'Eşzamanlı' ad alanını kullanmak istemedim, çünkü toplama sınıflarında 'eşzamanlı erişim' anlamına gelen zaten kullanılıyor. Uzlaşma olarak 'Paralelleştirilmiş' alt ad alanını seçtim.
redcalx

3

Bu, esasen karşıt iki cevabın her ikisinin de doğru olduğu gerçekten ilginç bir soru. İşte benim bir proje hakkında yaptığımız bu tartışmanın gerçek dünya örneği .

@Jorg ve @Frank'in iki cevabından yararlanarak, şu ana kadar bir yöne veya diğerine gitmek istemenizi sağlayacak çok dikkat çekici iki husus olduğunu düşünüyorum:

  1. Aynı kod bağlamında aynı adlı sınıflardan birden fazlasının kullanılması gerekebileceğini düşünüyorsanız, bu aynı adı kullanmamak için bir nedendir. Yani, birlikte çalışmanız gerekiyorsa, hr.Employeeancak aynı zamanda izinlere de bakmanız gerekiyorsa security.Employee, can sıkıcı gerçek hızlı olacak.
  2. Tersine, aynı ada sahip sınıflarınızın hepsi aynı veya çok benzer API'lara sahipse , aynı adı farklı ad alanlarıyla ne zaman kullanmanız gerektiğine iyi bir örnektir . Scala örneği, tüm Mapsınıfların aynı arabirimi uyguladığı veya birbirlerinin alt sınıfları olduğu tam olarak budur . Bu durumda, belirsizlik veya "karışıklık" tartışmalı olarak iyi bir şey olarak adlandırılabilir, çünkü kullanıcı haklı olarak sınıfın veya arayüzün tüm uygulamalarına aynı şekilde davranabilir ... bu da arayüzlerin ve alt sınıfların noktasıdır.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.