C#'tan Java'ya Çeviri – Java Ortamında .NET Framework Mantığını Kullanma

Bir projeyi bir dilden diğerine çevirmek, sadece kaynak kodu değişiklikleriyle ilgili değildir; aynı zamanda projeyi yürüttüğümüz ortamla da ilgilidir. CodePorting.Translator Java Class Library, bu tür bir ortamı JCL (Java sınıf kütüphanesi) üzerine uygular ve .NET Framework sınıf kütüphanesinin mantığını ve yapısını korur. Bu, çevrilen bir projenin kendini evinde hissetmesini sağlar ve Java platformu uygulamasından gizler.

CodePorting.Translator Java Class Library

JCL (Java sınıf kütüphanesi), genel tasarım, istisna işleme ve mantık açısından .NET sınıf kütüphanesinden farklılık gösterir. Bu nedenle, kodumuzu C# dilinden Java'ya çevirmeye karar verirsek, sadece sınıf ve işlev adlarını değiştirmek güvenli olmaz. .NET Framework sınıf kütüphanesi mantığını yeniden üretecek sargı kodu oluşturmanın bir çözümü olabilir. Ancak bu şekilde elde edilen Java kodu, orijinal C# kodundan önemli ölçüde farklı olur ve bu da beklentimiz değildir –- bir çevirmenin orijinal program yapısını korumasını istiyoruz. İşte burada .NET framework sınıf kütüphanesinin bir Java sürümünü uygulama ihtiyacı ortaya çıkıyor.

Nasıl Çalışır

Basit bir örnekle başlayalım:

using System;

class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Hello, Example!");
    }
}

Burada .NET Framework sınıf kütüphanesinden bir sınıfımız var – System.Console. Çevrilen Java kodu nasıl görünecektir?

import com.codeporting.ms.System.Console;

class Program
{
    public static void main(String[] args)
    {
        Console.writeLine("Hello, Example!");
    }
}

Görebileceğiniz gibi, çevirmen C# System.Console sınıfının referansını Java com.codeporting.ms.System.Console sınıfıyla değiştirir ve bu sınıf CodePorting.Translator Java Class Library'nde uygulanır.

Şimdi başka bir örneğe bakalım:

using System;
using System.Collections.Generic;

class Program
{
    public static void Main(string[] args)
    {
        PrintList(new List<string> { "Hello, list!", "I have a list for you to print!" });
    }
    public static void PrintList(List<string> list)
    {
        foreach(var item in list) Console.WriteLine(item);
    }
}

Çevrilen Java kodu şu şekildedir:

import com.codeporting.ms.System.Collections.Generic.IGenericEnumerable;
import com.codeporting.ms.System.Collections.Generic.List;
import com.codeporting.ms.System.Console;
import com.codeporting.ms.System.IDisposable;
import java.util.Iterator;

class Program
{
    public static void main(String[] args)
    {
        List<String> tmp = new List<String>();
        tmp.addItem("Hello, list!");
        tmp.addItem("I have a list for you to print!");
        printList(tmp);
    }
    public static void printList(IGenericEnumerable<String> list)
    {
        //Foreach to while statement conversion
        Iterator<String> variable1 = list.iterator();
        try
        {
            while (variable1.hasNext())
            {
                String item = variable1.next();
                Console.writeLine(item);
            }
        }
        finally
        {
            if (variable1 != null)
            {
                ((IDisposable)variable1).dispose();
            }
        }
    }
}

Burada CodePorting.Translator Java Class Library kullanımının bir başka faydasını daha görüyoruz: C# soyutlamaları arasındaki ilişkileri koruyoruz. System.Collections.Generic.List, IEnumerable arayüzünü uygular ve bu sayede foreach döngüsü kullanarak içinden geçebiliriz. Java'da java.lang.Iterable arayüzü vardır ve IEnumerable'a benzer görünse de, tasarım açısından küçük farklılıkları vardır ki bu büyük bir projede önemli olabilir.

Genel API saflığı

Güzel bir kütüphanemiz olsa da, çevirdiğimiz bir projenin müşteriler tarafından erişilebilir ve anlaşılabilir olması gerekir ve müşteriler JCL sınıflarını tercih edebilir. CodePorting.Translator Java Class Library'ni kullandığımızı dış dünyadan gizlemek iyi olurdu. İşte burada başka bir ilginç CodePorting.Translator özelliği daha var: ApiChange. Bu özellik ne işe yarar? CodePorting.Translator Java Class Library'ni kullanan yöntemleri gizler ve JCL sınıflarını kullanan proxy yöntemleri oluşturur. Bir örneğe bakalım:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Newspaper
{
    public class Article
    {
        public DateTime Published { get; set; }
        public string Content { get; set; }
    }

    public class Archive
    {
        List<Article> articles = new List<Article>();

        public void AddArticle(Article article)
        {
            articles.Add(article);
        }

        public IEnumerable<Article> GetArticlesForPeriod(DateTime start, DateTime end)
        {
            if(start > end || start > DateTime.Now)
            {
                return new Article[0];
            }
            return articles.Where(article => article.Published >= start && article.Published <= end);
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var archive = new Archive();
            archive.AddArticle(
                new Article() {
                    Published = new DateTime(2012, 12, 20), Content = "End of the world comes tomorrow!" });
            archive.AddArticle(
                new Article() {
                    Published = new DateTime(2012, 12, 22), Content = "It was a huge joke..." });
            var articles = archive.GetArticlesForPeriod(
                new DateTime(2000, 1, 1),
                new DateTime(2012, 12, 21));
            foreach(var article in articles)
            {
                Console.WriteLine(article.Content);
            }
        }
    }
}

Burada, bazı makaleleri depolayan ve yayınlandığı tarihe göre filtre uygulayan basit bir Archive sınıfı görüyorsunuz. System.DateTime sınıfı .NET Framework sınıf kütüphanesinin bir parçasıdır ve projemizde kullanabiliriz, ancak dış dünyadan gizlemek istiyoruz:

Article.java

package Newspaper;

import com.codeporting.ms.System.DateTime;
import java.util.Date;

public class Article
{
    private DateTime auto_Published = new DateTime();
    final DateTime getPublishedInternal() { return auto_Published.Clone(); }
    public final Date getPublished() {
        return DateTime.toJava(getPublishedInternal());
    }
    final void setPublishedInternal(DateTime value) { auto_Published = value.Clone(); }
    public final void setPublished(Date value) {
        setPublishedInternal(DateTime.fromJava(value));
    }
    private String auto_Content;
    public final String getContent() { return auto_Content; }
    public final void setContent(String value) { auto_Content = value; }
}

Archive.java

package Newspaper;

import com.codeporting.ms.System.Collections.Generic.IGenericEnumerable;
import com.codeporting.ms.System.Collections.Generic.List;
import com.codeporting.ms.System.DateTime;
import com.codeporting.ms.System.Func;
import java.util.Date;

public class Archive
{
    private Archive[] Archive_this = {this};
    private List<Article> articles = new List<Article>();

    public final void addArticle(Article article)
    {
        articles.addItem(article);
    }

    final IGenericEnumerable<Article> getArticlesForPeriodInternal(DateTime start, DateTime end)
    {
        if(DateTime.op_GreaterThan(start, end) || DateTime.op_GreaterThan(start, DateTime.getNow()))
        {
            return com.codeporting.ms.System.Array.<Article>toGenericList(new Article[0]);
        }
        return articles.where(new Func<Article,Boolean>() {
            public String getDelegateId() {
                return System.identityHashCode(Archive_this[0]) + "-89480671";
            }
            public Boolean invoke(Newspaper.Article article) {
                return DateTime.op_GreaterThanOrEqual(article.getPublishedInternal(), start) 
                    && DateTime.op_LessThanOrEqual(article.getPublishedInternal(), end);
            }
        });
    }

    public final java.lang.Iterable<Article> getArticlesForPeriod(Date start, Date end)
    {
        IGenericEnumerable<Article> temp=getArticlesForPeriodInternal(
            DateTime.fromJava(start),
            DateTime.fromJava(end));
        java.util.ArrayList<Article> temp_java=new java.util.ArrayList<Article>();
        {
            com.codeporting.ms.System.Collections.Generic.IGenericEnumerator<Article> temp_iterator=temp.iterator();
            while(temp_iterator.hasNext())
            {
                Article element=temp_iterator.next();
                temp_java.add(element);
            }
        }
        return temp_java;
    }
}

Program.java

package Newspaper;

import com.codeporting.ms.System.Collections.Generic.IGenericEnumerable;
import com.codeporting.ms.System.Console;
import com.codeporting.ms.System.DateTime;
import com.codeporting.ms.System.IDisposable;
import java.util.Iterator;

public class Program
{
    public static void main(String[] args)
    {
        Archive archive = new Archive();
        Article tmp = new Article();
        tmp.setPublishedInternal(new DateTime(2012, 12, 20));
        tmp.setContent("End of the world comes tomorrow!" ) ;
        archive.addArticle(tmp);
        Article tmp_1 = new Article();
        tmp_1.setPublishedInternal(new DateTime(2012, 12, 22));
        tmp_1.setContent("It was a huge joke..." ) ;
        archive.addArticle(tmp_1);
        IGenericEnumerable<Article> articles = archive.getArticlesForPeriodInternal(
	        new DateTime(2000, 1, 1),
	        new DateTime(2012, 12, 21));
        //Foreach to while statement conversion
        Iterator<Article> variable1 = articles.iterator();
        try
        {
            while (variable1.hasNext())
            {
                Article article = variable1.next();
                Console.writeLine(article.getContent());
            }
        }
        finally
        {
            if (variable1 != null)
            {
                ((IDisposable)variable1).dispose();
            }
        }
    }
}

Çevrilen Java kodu, CodePorting.Translator Java Class Library'ne genel API üzerinden erişim sağlamaz ve dış Java dünyası, genel proxy yöntemlerini kullanarak Archive sınıfıyla etkileşimde bulunabilir.

Sonuç olarak

CodePorting.Translator Java Class Library, JCL üzerinde bir soyutlama katmanı ve kontrol sağlar, bu da bizi uygulama ayrıntılarından uzaklaştırır ve çözmeye çalıştığımız sorunlar hakkında düşünmemizi sağlar.
Ayrıca, çeviri sonucunun yapısını korumaya yardımcı olur ve anlama ve şeffaflığı artırır.

İlgili makaleler