Selamlar, bugün "Nasıl temiz kod yazılır" serisinin 5 bölümü olan Biçimlendirme ile birlikteyiz.
Bu seri nedir ne değildir derseniz;
Serinin bir önceki konularına aşağıdan ulaşabilirsiniz,
Nasıl Temiz Kod Yazılır Serisi | Bölüm 4 Yorumlar
Nasıl temiz kod yazılır serisi #3 Fonksiyonlar
Bu seriye başlamak için gereksinimler:
- Temel düzeyde OOP programlama bilgisi
Bilmiyorum ne yapacağım?
JavaScript öğrenebilirsin bu serimizden;
JavaScripti sevmedim başka bir şey yok mu? var,
Dart dilini öğrenebilirsin! Bu serimizden;
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #7
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #8
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #9
BÖLÜM 6: NESNELER, YAPILAR data abstraction, Demeter Yasası | BÖLÜM 7: ERROR HANDLING exceptionları return yerine kullanmak, try catch finally yazmak, kontrol edilmemiş exceptionlar, context hakkında, null döndürmemek, null geçmemek | BÖLÜM 8: SINIRLAR 3.taraf kodlar hakkında, sınırları keşfetmek | |
BÖLÜM 9: UNIT TESTLER TDD yasaları, temiz testler, F.I.R.S.T. | BÖLÜM 10: SINIFLAR sınıfları organize etmek, | BÖLÜM 11: SİSTEMLER şehir oluşturmak, ayıklama, scale etme, karar vermek | BÖLÜM 12: TEKRAR ETMEMEK minimal sınıflar ve metodlar, tekrar etmeme, design rulelar hakkında |
BÖLÜM 13: CONCURRENCY bazı prensipler, kütüphaneni bilmek, senkronize metodlar hakkında | BÖLÜM 14: İYİLEŞTİRME | BÖLÜM 15: JUnit INTERNALS ek şeyler | BÖLÜM 16: EK KISIM |
BÖLÜM 17: DİĞERLERİ yorumlar, çevre, argümanlar, fonksiyonlar, genel bazı şeyler, algoritmayı anlamak, uzun import listelerinden kurtulma, constantlar vs enumlar, isim seçmeceler, testler | BÖLÜM 18: İLERİYE client server ilişkisi, pathler, deadlock, multithreaded kodu test etmece, bazı sağlam örnekler | BÖLÜM 19: ORG.JFREE.DATE.SERIALDATE | BÖLÜM 20: SON Temiz kod serisinin özetleri ve Îmam-ı Gazzâlî'den sana öğütler |
Uzatmadan konumuza geçelim;
Bugün ki işleyeceğimiz kısım Formatting yani Biçimlendirme.
~ Bir kodun profesyonel çalıştığını hissetmek istiyoruz.
Bunun için, sarhoş denizciler tarafından yazılmış gibi görünen karmakarışık bir kod yığınıyla karşılaşırlarsak
, projedeki diğer tüm yönlerde de aynı dikkatsizliğin hakim olduğunu düşünmemiz muhtemeldir.
Kodun Biçimlendirilmesi
Kodunuzun düzgün biçimlendirilmiş olmasına özen göstermelisiniz.
Kodunuzun biçimini belirleyen basit kurallar dizisini seçmeli ve bu kuralları tutarlı bir şekilde uygulamalısınız.
Bir ekip içinde çalışıyorsanız, ekip tek bir biçimlendirme kural seti üzerinde anlaşmalı ve tüm üyeler buna uymalıdır.
Bu kuralları sizin için otomatik olarak uygulayabilen bir araç kullanmanız faydalı olacaktır.
Biçimlendirmenin Amacı
Öncelikle şunu netleştirelim; Kod biçimlendirme önemlidir.
Göz ardı edilemeyecek kadar önemlidir ve körü körüne uygulanamayacak kadar da önemlidir.
Kod biçimlendirme, iletişimle ilgilidir ve profesyonel bir geliştiricinin öncelikli görevi iletişimdir.
Belki de bir profesyonel geliştiricinin ilk önceliğinin “kodun çalışmasını sağlamak” olduğunu düşünüyordunuz.
Bugün yazdığınız işlevsellik, bir sonraki sürümde değişme ihtimali yüksek olsa da, kodunuzun okunabilirliği, gelecekte yapılacak tüm değişiklikler üzerinde derin bir etkiye sahip olacaktır.
Kodlama tarzınız ve okunabilirliğiniz, kod tamamen tanınmaz hale geldikten çok sonra bile, sürdürülebilirlik ve genişletilebilirlik açısından etkisini sürdürecektir. K
odunuz değişse bile, disiplininiz ve tarzınız yaşamaya devam eder.
Peki, en iyi iletişimi sağlamak için hangi biçimlendirme konularına dikkat etmeliyiz? Cevaplayalım;
Dikey Biçimlendirme
Öncelikle dikey boyuttan başlayalım.
Bir kaynak dosyası ne kadar büyük olmalıdır?
Java’da dosya boyutu genellikle sınıf boyutuyla yakından ilişkilidir.
Sınıfları ele aldığımızda bu konuyu detaylıca inceleyeceğiz, ancak şimdilik sadece dosya boyutunu düşünelim.
Çoğu Java kaynak dosyası ne kadar büyük?
Oldukça geniş bir boyut aralığına sahipler ve farklı projeler arasında dikkate değer biçim farkları var.
Örnekte, bu farklılıkları göstermektedir.
Gazete Metaforu
İyi yazılmış bir gazete makalesini düşünün, Onu dikey olarak okursunuz.
En üstte, makalenin ne hakkında olduğunu size söyleyen ve okumaya değer olup olmadığına karar vermenizi sağlayan bir başlık beklersiniz.
İlk paragraf, tüm hikâyenin bir özetini sunar; tüm ayrıntıları gizleyerek ana konseptleri verir.
Aşağı doğru ilerledikçe ayrıntılar artar ve tarihleri, isimleri, alıntıları, iddiaları ve diğer tüm detayları öğrenirsiniz.
Bir kaynak dosyasının da bir gazete makalesine benzemesini isteriz.
Adı basit ama açıklayıcı olmalıdır. Sadece adıyla bile doğru modülde olup olmadığımızı anlamamızı sağlamalıdır.
Kaynak dosyanın en üst bölümleri, üst düzey bilgileri sunmalıdır.
Konseptler Arasındaki Dikey Açıklık
Neredeyse tüm kodlar soldan sağa ve yukarıdan aşağıya doğru okunur.
Her satır bir ifade veya cümlecik içerirken, satır grupları tamamlanmış düşünceleri temsil eder.
Bu düşünceler birbirlerinden boş satırlarla ayrılmalıdır.
Örnek ile ele alalım.
Paket bildirimi, import ifadeleri ve her fonksiyon arasında boş satırlar vardır.
Bu son derece basit kural, kodun görsel düzeni üzerinde derin bir etki yaratır.
Her boş satır, yeni ve bağımsız bir konsepti belirten görsel bir ipucu görevi görür.
Aşağı doğru tarama yaptığınızda, gözünüz boş satırdan sonra gelen ilk satıra odaklanır;
Kod:
package fitnesse.wikitext.widgets;
import java.util.regex.*;
public class BoldWidget extends ParentWidget {
public static final String REGEXP = "'''.+?'''";
private static final Pattern pattern = Pattern.compile("'''(.+?)'''",
Pattern.MULTILINE + Pattern.DOTALL
);
public BoldWidget(ParentWidget parent, String text) throws Exception {
super(parent);
Matcher match = pattern.matcher(text);
match.find();
addChildWidgets(match.group(1));
}
public String render() throws Exception {
StringBuffer html = new StringBuffer("<b>");
html.append(childHtml()).append("</b>");
return html.toSt
Dikey Yoğunluk
Açıklık konseptleri birbirinden ayırırken, dikey yoğunluk ise yakın ilişkili satırları bir arada tutar.
Yani, birbiriyle doğrudan bağlantılı kod satırları dikey olarak yoğun olmalıdır.
Örnekteki gereksiz yorum satırlarının, iki örnek değişken arasındaki yakın ilişkiyi nasıl bozduğuna dikkat edin.
Gereksiz boşluklar veya yorumlar, mantıksal olarak ilişkili kod satırlarının birbirinden kopuk görünmesine neden olabilir.
Bu yüzden, anlam bütünlüğü olan kod bloklarını dikey olarak bir arada tutmak önemlidir.
Kod:
public class ReporterConfig {
/**
* The class name of the reporter listener
*/
private String m_className;
/**
* The properties of the reporter listener
*/
private List<Property> m_properties = new ArrayList<Property>();
public void addProperty(Property property) {
m_properties.add(property);
}
Dikey Mesafe
Hiç bir sınıf içinde fonksiyonlar arasında gidip gelerek, dosya boyunca yukarı ve aşağı kaydırarak, fonksiyonların nasıl ilişkilendiğini ve çalıştığını anlamaya çalıştınız mı?
Sonunda kendinizi tam bir karmaşa içinde kaybolmuş hissettiniz mi?
Bir değişken ya da fonksiyonun tanımını bulmak için kalıtım zincirini yukarı doğru takip etmek zorunda kaldınız mı?
Bu oldukça sinir bozucu bir durumdur çünkü sistemin ne yaptığını anlamaya çalışırken, aslında enerjinizi ve zamanınızı sadece kodun farklı parçalarını bulmaya ve hatırlamaya harcamış olursunuz.
Birbirleriyle yakından ilişkili kavramlar dikey olarak yakın tutulmalıdır. Elbette, farklı dosyalara ait kavramlar için bu kural geçerli değildir.
Ancak, çok yakın ilişkili kavramları farklı dosyalara ayırmak için gerçekten geçerli bir nedeniniz olmalıdır.
Aslında, bu yüzden Protected değişkenlerin kullanımı genellikle önerilmez.
Değişken Bildirimleri
Değişkenler, kullanımına en yakın yerde tanımlanmalıdır.
Çünkü fonksiyonlarımız oldukça kısa olmalıdır, bu yüzden yerel değişkenler her fonksiyonun başında yer almalıdır.
Bu, kodun okunabilirliğini artırır ve değişkenlerin nerede kullanıldığını hızlıca anlamamızı sağlar.
Uzun bir fonksiyon içinde bile, değişkenlerin mümkün olduğunca yakın bir yerde tanımlanması,
kodun daha düzenli ve anlaşılır olmasına katkıda bulunur;
Kod:
private static void readPreferences() {
InputStream is= null;
try {
is= new FileInputStream(getPreferencesFile());
setPreferences(new Properties(getPreferences()));
getPreferences().load(is);
} catch (IOException e) {
try {
if (is != null)
is.close();
} catch (IOException e1) {
}
}
}
Değişken Bildirimleri - Nadir Durumlar
Nadir durumlarda, bir değişken bir bloğun başında veya uzun bir fonksiyondan hemen önce tanımlanabilir.
Bu tür bir değişkeni, Örnekteki çok uzun bir fonksiyondan alınan bu kod kesitinde görebilirsiniz.
Bu durumda, fonksiyon uzun olduğunda veya belirli bir bloğa özgü değişkenler, değişkenlerin fonksiyonun başında değil, ihtiyaç duyulan yerlerde tanımlanması gerekebilir.
Ancak, bu yaklaşım yalnızca gerçekten gerekli olduğunda ve kodun anlaşılabilirliğini engellemeyecek şekilde kullanılmalıdır.
Kod:
for (XmlTest test : m_suite.getTests()) {
TestRunner tr = m_runnerFactory.newTestRunner(this, test);
tr.addListener(m_textReporter);
m_testRunners.add(tr);
invoker = tr.getInvoker();
for (ITestNGMethod m : tr.getBeforeSuiteMethods()) {
beforeSuiteMethods.put(m.getMethod(), m);
}
for (ITestNGMethod m : tr.getAfterSuiteMethods()) {
afterSuiteMethods.put(m.getMethod(), m);
}
}
Örnek Değişkenler
Örnek değişkenleri, sınıfın en üst kısmında tanımlanmalıdır.
Bu, bu değişkenlerin dikey mesafesini artırmamalıdır çünkü iyi tasarlanmış bir sınıfta, bu değişkenler sınıfın birçok metoduyla kullanılmaktadır.
Örnek değişkenlerin nerede tanımlanması gerektiği konusunda pek çok tartışma olmuştur.
C++'ta, örnek değişkenlerini sınıfın alt kısmına yerleştiren "makas kuralı" yaygın bir uygulamaydı.
Ancak Java'da, yaygın olan gelenek, tüm örnek değişkenlerini sınıfın üst kısmına koymaktır.
Ben başka bir geleneği takip etmek için bir sebep görmüyorum.
Önemli olan, örnek değişkenlerin tek bir, herkesin bildiği yerde tanımlanmasıdır.
Herkes, bu tanımlamaları görmek için nereye gitmesi gerektiğini bilmelidir.
Kod:
public class TestSuite implements Test {
static public Test createTest(Class<? extends TestCase> theClass,
String name) {
Slow
}
Bağımlı Fonksiyonlar
Bir fonksiyon diğerini çağırıyorsa, bu fonksiyonlar dikey olarak yakın olmalı ve mümkünse çağıran (caller), çağrılan (callee) fonksiyondan önce yer almalıdır.
Bu, programa doğal bir akış kazandırır.
Eğer bu gelenek tutarlı bir şekilde izlenirse, okuyucular, fonksiyon tanımlarının kullanımlarının hemen ardından geleceğine güvenebilirler.
Aşağıdaki Örnekte'teki alınan bir kesiti düşünelim.
En üstteki fonksiyonların, altlarındaki fonksiyonları nasıl çağırdığına dikkat edin ve onların da aşağıdaki fonksiyonları nasıl çağırdığına bakın.
Bu düzen, çağrılan fonksiyonları bulmayı kolaylaştırır ve tüm modülün okunabilirliğini büyük ölçüde artırır.
Kod:
public class WikiPageResponder implements SecureResponder {
protected WikiPage page;
protected PageData pageData;
protected String pageTitle;
protected Request request;
protected PageCrawler crawler;
public Response makeResponse(FitNesseContext context, Request request)
throws Exception {
String pageName = getPageNameOrDefault(request, "FrontPage")
Konseptüel Yakınlık
Bazı kod parçaları, diğer kod parçalarına yakın olmayı ister. Bunların belirli bir konseptüel yakınlığı vardır.
Bu yakınlık ne kadar güçlü olursa, aralarındaki dikey mesafe o kadar az olmalıdır.
Gördüğümüz gibi, bu yakınlık, bir fonksiyonun diğerini çağırması veya bir fonksiyonun bir değişken kullanması gibi doğrudan bir bağımlılığa dayalı olabilir.
Ancak, yakınlığın başka nedenleri de olabilir. Bir grup fonksiyon benzer bir işlem gerçekleştirdiği için yakınlık oluşabilir.
Örneğin, Aşağıdaki örnekten alınan bu kod kesitini düşünelim.
Burada, benzer işlevleri yerine getiren fonksiyonlar arasındaki yakınlık, kodun mantığını daha anlaşılır hale getirir ve okuyucunun kodu daha rahat takip etmesini sağlar.
Kod:
public class Assert {
static public void assertTrue(String message, boolean condition) {
if (!condition)
fail(message);
}
static public void assertTrue(boolean condition) {
assertTrue(null, condition);
}
static public void assertFalse(String message, boolean condition) {
assertTrue(message, !condition);
}
static public void assertFalse(boolean condition) {
assertFalse(null, condition);
}
Dikey Sıralama
Genel olarak, fonksiyon çağrılarına dayalı bağımlılıkların aşağıya doğru yönlendirilmesini isteriz.
Yani, çağrılan bir fonksiyon, çağrıyı yapan fonksiyondan aşağıda olmalıdır.
Bu, kaynak kodu modülünde yüksek seviyeden düşük seviyeye doğru güzel bir akış yaratır.
Gazete makalelerinde olduğu gibi, en önemli kavramların önce gelmesini bekleriz ve bunların en az kirletici detaylarla ifade edilmesini bekleriz.
Düşük seviyeli detayların ise en sona gelmesini bekleriz.
Bu, kaynak dosyaları gözden geçirdiğimizde, ana fikri hızlıca alabilmemizi sağlar.
Yatay Formatlama
Bir satır ne kadar geniş olmalıdır?
Bunu cevaplamak için, tipik programlardaki satır genişliklerine bakalım.
Yine, yedi farklı projeyi inceledik.
Örnekteki yedi projenin tüm satır uzunluklarının dağılımını gösteriyor.
Düzenlilik etkileyici, özellikle 45 karakter civarında.
Gerçekten de, 20 ile 60 arasındaki her boyut, toplam satır sayısının yaklaşık %1'ini temsil ediyor.
Bu, %40'a denk geliyor! Belki bir başka %30'u 10 karakterden kısa satırlardan oluşuyor.
Unutmayın, bu bir logaritmik ölçektir, bu yüzden 80 karakterin üzerindeki düşüşün doğrusal görünümü aslında oldukça anlamlıdır.
Programcılar açıkça kısa satırlardan yana tercih yapıyorlar.
Kod:
private void measureLine(String line) {
lineCount++;
int lineSize = line.length();
totalChars += lineSize;
lineWidthHistogram.addLine(lineSize, lineCount);
recordWidestLine(lineSize);
}
Yatay Hizalama
Ben bir Assembly dili programcısı iken, belirli yapıları vurgulamak için yatay hizalamayı kullanırız.
C, C++ ve nihayetinde Java'da kod yazmaya başladığımda, tüm değişken isimlerini bir dizi bildiride veya tüm sağ değerleri bir dizi atama ifadesinde hizalamaya çalışmaya devam ettim.
Kodum şu şekilde görünüyor olabilirdi;
Kod:
public class FitNesseExpediter implements ResponseSender
{
private Socket socket;
private InputStream input;
private OutputStream output;
private Request request;
private Response response;
private FitNesseContext context;
protected long requestParsingTimeLimit;
private long requestProgress;
private long requestParsingDeadline;
private boolean hasError;
public FitNesseExpediter(Socket s,
FitNesseContext context) throws Exception
{
this.context = context;
socket = s;
input = s.getInputStream();
output = s.getOutputStream();
requestParsingTimeLimit = 10000;
}
Bu tür hizalamalar, kodun okunabilirliğini artırmak ve yapıların daha kolay anlaşılmasını sağlamak amacıyla yaygın bir yöntemdi.
Ancak, modern yazılım geliştirme ortamlarında,
genellikle yatay hizalamanın gereksiz olduğu ve kodun otomatik formatlayıcılar tarafından düzenlenmesi gerektiği görüşü benimsenmiştir.
Girinti (Indentation)
Bir kaynak dosyası, tıpkı bir taslak gibi bir hiyerarşidir.
Dosya geneliyle, dosya içindeki bireysel sınıflarla, sınıflardaki metodlarla, metodlardaki bloklarla ve bu bloklar içindeki alt bloklarla ilgili bilgiler vardır.
Bu hiyerarşinin her seviyesi, isimlerin bildirilebileceği ve bildirimlerin ve çalıştırılabilir ifadelerin yorumlanacağı bir kapsamdır.
Bu kapsamlar hiyerarşisini görünür kılmak için, kaynak kodu satırlarını hiyerarşilerindeki konumlarına orantılı olarak girintileriz.
Dosya seviyesinde, çoğu sınıf bildirimleri gibi ifadeler hiç girintilenmez.
Bir sınıf içindeki metodlar, sınıfın bir seviyesinin sağında girintilenir.
O metodların implementasyonları, metod bildirimlerinin bir seviyesinin sağında yer alır.
Blok implementasyonları ise kendi içerdiği bloğun bir seviyesinin sağında yer alır ve bu şekilde devam eder.
Programcılar, bu girinti düzenine büyük ölçüde güvenirler.
Solda hizalanmış satırları gözlemlerler, böylece hangi kapsamda olduklarını kolayca anlayabilirler.
Bu sayede, şu anki durumlarına uygun olmayan IF veya While gibi yapıların Implementasyonları gibi kapsamları hızlıca atlayabilirler.
Yeni metod bildirimleri, yeni değişkenler ve hatta yeni sınıfları sol taraftan tarayarak bulurlar.
Girinti olmadan, programlar insanlar tarafından neredeyse okunamaz hale gelir
Aşağıdaki örnekleri düşünelim; bu programlar söz dizimsel ve anlamsal olarak birbirine eşittir;
Kod:
context; public FitNesseServer(FitNesseContext context) { this.context =
context; } public void serve(Socket s) { serve(s, 10000); } public void
serve(Socket s, long requestTimeout) { try { FitNesseExpediter sender = new
FitNesseExpediter(s, context);
sender.setRequestParsingTimeLimit(requestTimeout); sender.start(); }
catch(Exception e) { e.printStackTrace(); } } }----
public class FitNesseServer implements SocketServer {
private FitNesseContext context;
Girinti Kuralını İhlal Etme (Breaking Indentation)
Bazen, kısa IF ifadeleri, kısa While döngüleri veya kısa fonksiyonlar için girinti kuralını ihlal etmek cazip olabilir.
Ben bu temptasyona kapıldığımda, neredeyse her zaman geri dönüp girintiyi tekrar ekledim.
Bu nedenle, kapsamları bir satıra indirgemekten kaçınırım ve şu şekilde yazılmamalıdır;
Kod:
public class CommentWidget extends TextWidget
{
public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";
public CommentWidget(ParentWidget parent, String text){super(parent, text);}
public String render() throws Exception {return ""; }
}
Bu şekilde, bir ifadeyi tek satıra indirmek görünüşte daha kısa ve kolay olabilir, ancak bu, kodun okunabilirliğini büyük ölçüde azaltır.
Girinti, kodun yapısını ve kapsamını belirginleştirir, bu da başkalarının (veya kendi kendimize) kodu daha kolay anlamamıza yardımcı olur.
Bu nedenle, her zaman uygun girinti kullanmaya özen göstermeliyiz.
Takım Kuralları
Bu bölümün başlığı bir kelime oyunudur. Her programcının kendi favori formatlama kuralları vardır, ancak bir takımda çalışıyorsa, takımın kuralları geçerlidir.
Bir yazılım geliştirme ekibi, tek bir formatlama stilinde anlaşmalıdır ve ardından bu stil tüm ekip üyeleri tarafından kullanılmalıdır.
Yazılımın tutarlı bir stile sahip olmasını isteriz.
Bir grup tartışan birey tarafından yazılmış gibi görünmesini istemeyiz.
2002'de Örnekte projesine başladığımda, takım ile birlikte bir kodlama stili oluşturmak için oturduk.
Bu yaklaşık 10 dakika sürdü.
Parantezleri nereye koyacağımıza, girinti boyutumuzu nasıl belirleyeceğimize, sınıfları, değişkenleri ve metotları nasıl adlandıracağımıza karar verdik ve buna göre kuralları IDE'mizin kod formatlayıcısına kodladık ve o zamandan beri bu kurallara sadık kaldık.
Bunlar benim tercih ettiğim kurallar değildi; bunlar takım tarafından kararlaştırılmıştı.
O takımın bir üyesi olarak, Örneği projesinde kod yazarken bu kurallara uydum.
Unutmayın, iyi bir yazılım sistemi, okunması kolay bir dizi belgeden oluşur.
Bu belgeler tutarlı ve düzgün bir stile sahip olmalıdır.
Okuyucu, bir kaynak dosyasındaki formatlama işaretlerinin diğerlerinde de aynı anlama geleceğine güvenebilmelidir.
Son şeyimiz, kaynak kodunu farklı bireysel stillerin karışımıyla yazarak daha fazla karmaşıklık eklemek olacaktır.
Kod:
public class CodeAnalyzer implements JavaFileAnalysis {
private int lineCount;
private int maxLineWidth;
private int widestLineNumber;
private LineWidthHistogram lineWidthHistogram;
private int totalChars;
public CodeAnalyzer() {
lineWidthHistogram = new LineWidthHistogram();
}
public static List<File> findJavaFiles(File parentDirectory) {
List<File> files = new ArrayList<File>();
findJavaFiles(parentDirectory, files);
return files;
}
private static void findJavaFiles(File parentDirectory, List<File> files) {
for (File file : parentDirectory.listFiles()) {
if (file.getName().endsWith(".java"))
files.add(file);
else if (file.isDirectory())
findJavaFiles(file, files);
}
}
public void analyzeFile(File javaFile) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(javaFile));
String line;
while ((line = br.readLine()) != null)
measureLine(line);
}
private void measureLine(String line) {
lineCount++;
int lineSize = line.length();
totalChars += lineSize;
lineWidthHistogram.addLine(lineSize, lineCount);
recordWidestLine(lineSize);
}
private void recordWidestLine(int lineSize) {
if (lineSize > maxLineWidth) {
maxLineWidth = lineSize;
widestLineNumber = lineCount;
}
}
public int getLineCount() {
return lineCount;
}
public int getMaxLineWidth() {
return maxLineWidth;
}
Konu bu kadar, takıldığınız yerleri veya eleştirilerinizi yazabilirsiniz.
Şuan ki ilerleme oranımız 93/400
Son düzenleme:



