Tüm Platformlar için Hızlı Uygulama Geliştirme Kitap Yayın Süreci
Kitap gözden geçirilmek üzere BTG (Bilgi ve Teknoloji Grubu) 'na gönderildi. 05.10.2018-14:10
BTG (Bilgi ve Teknoloji Grubu) tarafından iki sayfalık bir reklam tasarımı bekleniyor. 08.10.2018 - 15:30

Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 2 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Class kullanımı hakkında
#1
Selam, az önce bişi denedim aklıma takılan bir olay var, 

type
  TCariKayit = class
  Kod    : Integer;
  Barkod : String[20];
  Unvan  : String[100];
 end;
............
implementation

{$R *.dfm}
function GetCariKayit: TCariKayit;
begin
Result := TCariKayit.Create;
  Result.Kod    := 0;
  Result.Barkod := '1234';
  Result.Unvan  := 'Njt Ltd.';
end;


Yukarıdaki şekilde bir tip ve fonksiyonum var, acaba aşağıdaki 2 kullanım şeklinden hangisi daha doğrudur?

1. kullanım şekli
procedure TForm1.Button1Click(Sender: TObject);
VAR
A:TCariKayit;
begin
A:=GetCariKayit;
Memo1.Lines.Add(INTTOSTR(A.Kod));
Memo1.Lines.Add(A.Barkod);
Memo1.Lines.Add(A.Unvan);
end;



2. kullanım şekli (Bu şekilde kullanmak daha mantıklı geliyor bana ama her satırda fonksiyonu çalıştırmış oluyoruz o yüzden sakıncalımıdır?)
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Add(INTTOSTR(GetCariKayit.Kod));
Memo1.Lines.Add(GetCariKayit.Barkod);
Memo1.Lines.Add(GetCariKayit.Unvan);
end;
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
WWW
Cevapla
#2
Selamün Aleyküm;
Eğer kod karmaşıklığı bu kadarsa her iki seçeneği de kullanabilirsin, hız farkının fark edileceğini zannetmiyorum. Diğer bir yöntem ise -ki bence böyle yapman iyi olur- fonksiyonu inline yaparsın ve fonksiyonun çağırıldığı yere fonksiyon içeriği yazılır ve fonksiyon çağırma maliyeti olmaz.
Cevapla
#3
Merhaba,

İkinci kullanım şekli kesinlikle yanlış Smile Bunun iki sebebi var:

1. TCariKayit tipi bir class ve GetCariKayit fonksiyonu TCariKayit sınıfından yeni bir nesne yaratıyor. Ama bu yaratılan nesne hiçbir zaman serbest bırakılmıyor. Dolayısıyla programınız bellekten sürekli yer alıyor ve vermiyor. (Memory Leak)

2. TCariKayit tipi bir record olsaydı bu sefer de performanstan dolayı doğru bir kullanım olmazdı. Her satırda aslında yeni bir record dolduruyorsunuz (ki belleği otomatik yönetmesine rağmen bu işlem de bellekten yer alacak ve geri bırakacak). Bu da ciddi performans kaybına sebep olabilir.

İlk kullanım da o kadar masum değil. Orada da bellek kaybı var. Onun da doğrusu şu şekilde olmalı:

procedure TForm1.Button1Click(Sender: TObject);
VAR
  A:TCariKayit;
begin
  A:=GetCariKayit;
  try
    Memo1.Lines.Add(INTTOSTR(A.Kod));
    Memo1.Lines.Add(A.Barkod);
    Memo1.Lines.Add(A.Unvan);
  finally
    A.Free;
  end;
end;

Bu arada bence kullandığınız tasarım biraz problemli. GetCariKayit fonksiyonu herhangi bir sebepten dolayı hata verecek olursa gene bellek kaybı olabilir. Tasarımınızı biraz daha geliştirip beklenmeyen bir hata oluştuğunda bellek kaybı olmayacak bir yapı kurmanızı tavsiye ederim.

İyi çalışmalar
Cevapla
#4
Selam, cevaplar için teşekkürler.
Bahadır hocam ben 1. şekilde kullanmam gerektiğine kanaat getirdim artık. Kodu öylesine test için yazmıştım, artık kodlarken gerekli güvenlik önlemlerini alıp ona göre yazarız. Memory leak vs. kontrolunu yaparız inşallah.

Asıl yazmak istediğim şu OOP olayına benzer, veritabanına verileri eklerken stored proc. lar ile etkileşimli çalışacak bişi yazmak.
Kısaca tablodaki field ve tiplere göre formdaki componentleri tarayıp stored proc. daki field ve tipler ile eşleştirip stored proc. u hazırlayıp, içini doldurup, yallah hamle kafire diyecek bi kod yazmayı düşünüyorum.
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
WWW
Cevapla
#5
Bence de 1. Kullanım şekli daha mantıklı
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Kuvvete dayanamayan adalet aciz, 
Adalete dayanamayan kuvvet zalimdir.
WWW
Cevapla
#6
Merhaba. Bende class içinden veri alma ile ilgili farklı bir yaklaşım yazmak istiyorum. Eğer amaç classı bir kere kullanıp verileri yüklemek ise ben genelde şöyle bir yöntem uygulamaktayım. Yazdığınız get metoduna içi doldurulacak nesneyi gönderip içini doldurduktan sonrada classı Free ediyorum. Yani :

unit Unit1;

interface

uses
 System.Classes, System.SysUtils;

type
 TCariKayit = class
 private
   FKod    : Integer;
   FBarkod : String[20];
   FUnvan  : String[100];
 public
   function AddKod(Kod:integer):TCariKayit;
   function AddBarkod(Barkod:String):TCariKayit;
   function AddUnvan(Unvan:String):TCariKayit;

   function ListCariKayit(List:TStrings):TCariKayit;
end;

function CreateCariKayit : TCariKayit ;

implementation


function CreateCariKayit : TCariKayit ;
begin
 Result := TCariKayit.Create;
end;

function TCariKayit.AddBarkod(Barkod: String): TCariKayit;
begin
 FBarkod := Barkod;
 Result := Self;
end;

function TCariKayit.AddKod(Kod: integer): TCariKayit;
begin
 FKod := Kod;
 Result := Self;
end;

function TCariKayit.AddUnvan(Unvan: String): TCariKayit;
begin
 FUnvan := Unvan;
 Result := Self;
end;

function TCariKayit.ListCariKayit(List:TStrings):TCariKayit;
begin
 try
   List.Add(inttostr(FKod));
   List.Add(FBarkod);
   List.Add(FUnvan);
 finally
   Result := TCariKayit;
 end;
end;

end.

Kullanımı:

uses Unit1
...
procedure TForm1.Button1Click(Sender: TObject);
begin
 CreateCariKayit
                 .AddKod('1')
                 .AddBarkod('1234')
                 .AddUnvan('Njt Ltd.')
               .ListCariKayit(Memo1.Lines)
               .Free
end;
WWW
Cevapla
#7
fluent api design yada fluent interface
One of the major software engineering challanges is managing change.
Cevapla
#8
fluent interface ' i seven destekleyen de var , nefret edip tavsiye etmeyen de var Smile

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
WWW
Cevapla
#9
En basit delphi'nin standart StringBuilder sınıfı örnek olarak verilebilir.
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

Diğer programlama dillerinde de fluent olarak tasarlandığını görmek mümkün.
One of the major software engineering challanges is managing change.
Cevapla
#10
Aynen fluent interface olarak geçiyor ben kod zincirleme diyorum. Bana göre kod karmaşıklığını gideren ve yönetimini kolaylaştıran bir yöntem . O yüzden de severek kullanıyorum. Bunun en güzel örneklerinden birini de mail göndermede görebiliriz. İnternette dolaşırken karşılaştığım mail gönderme Classını biraz değiştirerek kod zincirleme haline getirdim. Belki bazı arkadaşlara lazım olur diye buradan paylaşıyorum. İki metodu da içeriyor Class.

unit SendIndyMail;

interface

uses
 IdMessage, Classes, IdSMTP;

const
 SMTP_PORT_EXPLICIT_TLS = 587;

type
 TSSLEmail = class(TObject)
 private
   IdMessage: TIdMessage;
   SMTP: TIdSMTP;

   FBody: TStrings;
   FSMTPPort: Integer;
   FToEmail: string;
   FSubject: string;
   FSMTPServer: string;
   FCCEmail: string;
   FPassword: string;
   FBCCEmail: string;
   FSenderName: string;
   FUserName: string;
   FPriority: TIdMessagePriority;
   FSenderEmail: string;
   FSSLConnection: Boolean;

   // Getter / Setter
   procedure SetBody(const AValue: TStrings);

   procedure Init;
   procedure InitMailMessage;
   procedure InitSASL;
   procedure AddSSLHandler;

 public
   constructor Create; overload;
   constructor Create(const ASMTPServer: string;
     const ASMTPPort: Integer;
     const AUserName, APassword: string); overload;

   destructor Destroy; override;

   function SendEmail: TSSLEmail;

   // Properties
   function AddBCCEmail(AValue: string) : TSSLEmail;
   function AddBody(AValue: TStrings) : TSSLEmail;overload;
   function AddBody(AValue: string) : TSSLEmail;overload;
   function AddCCEmail(AValue: string) : TSSLEmail;
   function AddPassword(AValue: string) : TSSLEmail;
   function AddPriority(AValue: TIdMessagePriority) : TSSLEmail;
   function AddSenderEmail(AValue: string) : TSSLEmail;
   function AddSenderName(AValue: string) : TSSLEmail;
   function AddSMTPServer(AValue: string) : TSSLEmail;
   function AddSMTPPort(AValue: integer) : TSSLEmail;
   function AddSSLConnection(AValue: Boolean) : TSSLEmail;
   function AddToEmail(AValue: string) : TSSLEmail;
   function AddUserName(AValue: string) : TSSLEmail;
   function AddSubject(AValue: string) : TSSLEmail;

   property BCCEmail: string read FBCCEmail write FBCCEmail;
   property Body: TStrings read FBody write FBody;
   property CCEmail: string read FCCEmail write FCCEmail;
   property Password: string read FPassword write FPassword;
   property Priority: TIdMessagePriority read FPriority write FPriority;
   property SenderEmail: string read FSenderEmail write FSenderEmail;
   property SenderName: string read FSenderName write FSenderName;
   property SMTPServer: string read FSMTPServer write FSMTPServer;
   property SMTPPort: Integer read FSMTPPort write FSMTPPort;
   property SSLConnection: Boolean read FSSLConnection write FSSLConnection;
   property ToEmail: string read FToEmail write FToEmail;
   property UserName: string read FUserName write FUserName;
   property Subject: string read FSubject write FSubject;

 end;

function CreateSendMail:TSSLEmail;overload;
function CreateSendMail(const ASMTPServer: string;
 const ASMTPPort: Integer;
 const AUserName, APassword: string):TSSLEmail;overload;

implementation

uses
 IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
 IdMessageClient, IdSMTPBase, IdBaseComponent, IdIOHandler,
 IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdSASLLogin,
 IdSASL_CRAM_SHA1, IdSASL, IdSASLUserPass, IdSASL_CRAMBase, IdSASL_CRAM_MD5,
 IdSASLSKey, IdSASLPlain, IdSASLOTP, IdSASLExternal, IdSASLDigest,
 IdSASLAnonymous, IdUserPassProvider;

function CreateSendMail:TSSLEmail;overload;
begin
 Result := TSSLEmail.Create;
end;

function CreateSendMail(const ASMTPServer: string;
 const ASMTPPort: Integer;
 const AUserName, APassword: string):TSSLEmail;overload;
begin
 Result := TSSLEmail.Create(ASMTPServer,ASMTPPort,AUserName,APassword);
end;

constructor TSSLEmail.Create;
begin
 inherited;

 Init;

 FBody := TStringList.Create;
end;

procedure TSSLEmail.Init;
begin
 SSLConnection := True;
 Priority := TIdMessagePriority.mpNormal;
end;

function TSSLEmail.AddSubject(AValue: string): TSSLEmail;
begin
 FSubject := AValue;
 Result := Self;
end;

function TSSLEmail.AddToEmail(AValue: string): TSSLEmail;
begin
 FToEmail := AValue;
 Result := Self;
end;

function TSSLEmail.AddUserName(AValue: string): TSSLEmail;
begin
 FUserName := AValue;
 Result := Self;
end;

constructor TSSLEmail.Create(const ASMTPServer: string;
 const ASMTPPort: Integer; const AUserName, APassword: string);
begin
 Create;

 SMTPServer := ASMTPServer;
 SMTPPort := ASMTPPort;
 UserName := AUserName;
 Password := APassword;
end;

destructor TSSLEmail.Destroy;
begin
 FBody.Free;

 inherited;
end;

// Setter / Getter -----------------------------------------------------------

procedure TSSLEmail.SetBody(const AValue: TStrings);
begin
 FBody.Assign(AValue);
end;

// Send the mail -------------------------------------------------------------

function TSSLEmail.SendEmail:TSSLEmail;
begin
 IdMessage := TIdMessage.Create;
 try
   InitMailMessage;

   SMTP := TIdSMTP.Create;
   try
     if SSLConnection then
     begin
       AddSSLHandler;

       if SMTPPort = SMTP_PORT_EXPLICIT_TLS then
         SMTP.UseTLS := utUseExplicitTLS
       else
         SMTP.UseTLS := utUseImplicitTLS;
     end;

     if (UserName<>'') or (Password<>'') then
     begin
       SMTP.AuthType := satSASL;
       InitSASL;
     end
     else
     begin
       SMTP.AuthType := satNone;
     end;

     SMTP.Host := SMTPServer;
     SMTP.Port := SMTPPort;
     SMTP.ConnectTimeout := 30000;
     SMTP.UseEHLO := True;
     SMTP.Connect;

     try
       SMTP.Send(IdMessage);
     finally
       SMTP.Disconnect;
     end;
   finally
     SMTP.Free;
   end;
 finally
   IdMessage.Free;
 end;
 Result := Self;
end;

// Prepare the mail ----------------------------------------------------------

procedure TSSLEmail.InitMailMessage;
begin
 IdMessage.ContentType := 'text/plain';
 IdMessage.Charset := 'UTF-8';
 IdMessage.Body := Body;
 IdMessage.Sender.Text := SenderEMail;
 IdMessage.From.Name := SenderName;
 IdMessage.From.Address := SenderEMail;
 IdMessage.ReplyTo.EMailAddresses := SenderEmail;
 IdMessage.Recipients.EMailAddresses := ToEmail;
 IdMessage.Subject := Subject;
 IdMessage.Priority := Priority;
 IdMessage.CCList.EMailAddresses := CCEMail;
 IdMessage.ReceiptRecipient.Text := '';
 IdMessage.BccList.EMailAddresses := BCCEMail;
end;

function TSSLEmail.AddBCCEmail(AValue: string): TSSLEmail;
begin
 if FBCCEmail = '' then
   FBCCEmail := AValue
 else
   FBCCEmail := FBCCEmail+','+AValue;

 Result := Self;
end;

function TSSLEmail.AddBody(AValue: TStrings): TSSLEmail;
begin
 FBody.Add(AValue.Text);
 Result := Self;
end;

function TSSLEmail.AddBody(AValue: string): TSSLEmail;
begin
 FBody.Add(AValue);
 Result := Self;
end;

function TSSLEmail.AddCCEmail(AValue: string): TSSLEmail;
begin
 if FCCEmail = '' then
   FCCEmail := AValue
 else
   FCCEmail := FCCEmail +','+AValue;
 Result := Self;
end;

function TSSLEmail.AddPassword(AValue: string): TSSLEmail;
begin
 FPassword := AValue;
 Result := Self;
end;

function TSSLEmail.AddPriority(AValue: TIdMessagePriority): TSSLEmail;
begin
 FPriority := AValue;
 Result := Self;
end;

function TSSLEmail.AddSenderEmail(AValue: string): TSSLEmail;
begin
 FSenderEmail := AValue;
 Result := Self;
end;

function TSSLEmail.AddSenderName(AValue: string): TSSLEmail;
begin
 FSenderName := AValue;
 Result := Self;
end;

function TSSLEmail.AddSMTPPort(AValue: integer): TSSLEmail;
begin
 FSMTPPort := AValue;
 Result := Self;
end;

function TSSLEmail.AddSMTPServer(AValue: string): TSSLEmail;
begin
 FSMTPServer := AValue;
 Result := Self;
end;

function TSSLEmail.AddSSLConnection(AValue: Boolean): TSSLEmail;
begin
 FSSLConnection := AValue;
 Result := Self;
end;

procedure TSSLEmail.AddSSLHandler;
var
 SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
 SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(SMTP);
 // SSL/TLS handshake determines the highest available SSL/TLS version dynamically
 SSLHandler.SSLOptions.Method := sslvSSLv23;
 SSLHandler.SSLOptions.Mode := sslmClient;
 SSLHandler.SSLOptions.VerifyMode := [];
 SSLHandler.SSLOptions.VerifyDepth := 0;
 SMTP.IOHandler := SSLHandler;
end;

procedure TSSLEmail.InitSASL;
var
 IdUserPassProvider: TIdUserPassProvider;
 IdSASLCRAMMD5: TIdSASLCRAMMD5;
 IdSASLCRAMSHA1: TIdSASLCRAMSHA1;
 IdSASLPlain: TIdSASLPlain;
 IdSASLLogin: TIdSASLLogin;
 IdSASLSKey: TIdSASLSKey;
 IdSASLOTP: TIdSASLOTP;
 IdSASLAnonymous: TIdSASLAnonymous;
 IdSASLExternal: TIdSASLExternal;
begin
 IdUserPassProvider := TIdUserPassProvider.Create(SMTP);
 IdUserPassProvider.Username := UserName;
 IdUserPassProvider.Password:= Password;

 IdSASLCRAMSHA1 := TIdSASLCRAMSHA1.Create(SMTP);
 IdSASLCRAMSHA1.UserPassProvider := IdUserPassProvider;
 IdSASLCRAMMD5 := TIdSASLCRAMMD5.Create(SMTP);
 IdSASLCRAMMD5.UserPassProvider := IdUserPassProvider;
 IdSASLSKey := TIdSASLSKey.Create(SMTP);
 IdSASLSKey.UserPassProvider := IdUserPassProvider;
 IdSASLOTP := TIdSASLOTP.Create(SMTP);
 IdSASLOTP.UserPassProvider := IdUserPassProvider;
 IdSASLAnonymous := TIdSASLAnonymous.Create(SMTP);
 IdSASLExternal := TIdSASLExternal.Create(SMTP);
 IdSASLLogin := TIdSASLLogin.Create(SMTP);
 IdSASLLogin.UserPassProvider := IdUserPassProvider;
 IdSASLPlain := TIdSASLPlain.Create(SMTP);
 IdSASLPlain.UserPassProvider := IdUserPassProvider;

 SMTP.SASLMechanisms.Add.SASL := IdSASLCRAMSHA1;
 SMTP.SASLMechanisms.Add.SASL := IdSASLCRAMMD5;
 SMTP.SASLMechanisms.Add.SASL := IdSASLSKey;
 SMTP.SASLMechanisms.Add.SASL := IdSASLOTP;
 SMTP.SASLMechanisms.Add.SASL := IdSASLAnonymous;
 SMTP.SASLMechanisms.Add.SASL := IdSASLExternal;
 SMTP.SASLMechanisms.Add.SASL := IdSASLLogin;
 SMTP.SASLMechanisms.Add.SASL := IdSASLPlain;
end;

end.

Normal Kullanımı :

procedure TForm1.btnNormalClick(Sender: TObject);
var
 Mail: TSSLEmail;
begin
 try
   Mail := TSSLEmail.Create('smtp.gmail.com',
                             465,
                             'hakanucaar@gmail.com',
                             'KendiEmailŞifren'
                           );

   try
     Mail.SenderName := 'Hakan Uçar Inc.';
     Mail.SenderEmail := 'hakanucaar@example.com';
     Mail.ToEmail := 'hakanucaar@yandex.com';
     Mail.Subject := edtKonu.Text;
     Mail.Body := mmoMesaj.Lines;

     Mail.SendEmail;
   finally
     Mail.Free;
   end;
 finally
   ShowMessage('Mesaj Normal Metod ile Gönderildi');
 end;
end;


Kod Zincirleme :

procedure TForm1.btnKodZincirClick(Sender: TObject);
begin
 try
   CreateSendMail('smtp.gmail.com',
                   465,
                   'hakanucaar@gmail.com',
                   'KendiEmailŞifren'
                 )
                  .AddSenderName('Hakan Uçar Inc.')
                  .AddSenderEmail('hakanucaar@gmail.com')
                  .AddToEmail('hakanucaar@yandex.com')
                  .AddSubject(edtKonu.Text)
                  .AddBody(mmoMesaj.Lines)
                  .SendEmail
                  .Free;
 finally
   ShowMessage('Mesaj Kod Zincirleme Metodu ile Gönderildi');
 end;
end;

Görünüm:

SendMail.gif
WWW
Cevapla

Konuyu Paylaş : facebook gplus twitter



Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  JSON Bilgi Talebi, RAD 10 Seattle Yeni JSON Özellikleri Hakkında eroniko 4 117 13-10-2018, Saat: 21:59
Son Yorum: eroniko
  ClassType hakkında adelphiforumz 1 87 11-10-2018, Saat: 22:27
Son Yorum: sabanakman
  Inherited Formlar Hakkında Bilgi Talebi adelphiforumz 5 148 11-10-2018, Saat: 10:28
Son Yorum: adelphiforumz
  Firedac bileşenleri hakkında canbir 2 363 06-10-2018, Saat: 02:06
Son Yorum: Lord_Ares
  Aynı türden iki class'ı nasıl klonlarız? uparlayan 20 794 15-09-2018, Saat: 10:41
Son Yorum: ismailkocacan



Konuyu Okuyanlar: 1 Ziyaretçi