Məzmun
- Giriş
- İnterfeyslər
- İnterfeys markerləri
- Funksional interfeyslər, statik metodlar və standart metodlar
- Abstrakt dərslər
- Dəyişməz (daimi) siniflər
- Anonim siniflər
- Görünüş
- Miras
- Çoxlu miras
- Varislik və tərkibi
- İnkapsulyasiya
- Yekun dərslər və üsullar
- Sonra nə var
- Mənbə kodunu yükləyin
1. GİRİŞ
Hansı proqramlaşdırma dilindən istifadə etməyinizdən asılı olmayaraq (və Java da istisna deyil), yaxşı dizayn prinsiplərinə riayət etmək təmiz, başa düşülən və yoxlanıla bilən kod yazmağın açarıdır; və həmçinin uzun ömürlü olmaq və problemin həllini asanlıqla dəstəkləmək üçün yaradın. Dərsliyin bu hissəsində biz Java dilinin təmin etdiyi əsas tikinti bloklarını müzakirə edəcəyik və daha yaxşı dizayn qərarları qəbul etməyinizə kömək etmək üçün bir neçə dizayn prinsipini təqdim edəcəyik. Daha dəqiq desək, biz standart metodlardan (Java 8-də yeni xüsusiyyət), abstrakt və yekun siniflərdən, dəyişməz siniflərdən, mirasdan, kompozisiyadan istifadə edən interfeys və interfeysləri müzakirə edəcəyik və qısaca toxunduğumuz görünmə (və ya əlçatanlıq) qaydalarına yenidən baxacağıq. 1-ci hissə dərsi
"Obyektləri necə yaratmaq və məhv etmək" .
2. İNTERFEYSLER
Obyekt yönümlü proqramlaşdırmada interfeys anlayışı müqavilələrin inkişafı üçün əsas təşkil edir . Bir sözlə, interfeyslər bir sıra metodlar (müqavilələr) müəyyən edir və həmin xüsusi interfeys üçün dəstək tələb edən hər bir sinif həmin metodların həyata keçirilməsini təmin etməlidir: kifayət qədər sadə, lakin güclü ideya. Bir çox proqramlaşdırma dillərində bu və ya digər formada interfeyslər var, lakin xüsusilə Java bunun üçün dil dəstəyi təmin edir. Java-da sadə interfeys tərifinə nəzər salaq.
package com.javacodegeeks.advanced.design;
public interface SimpleInterface {
void performAction();
}
Yuxarıdakı fraqmentdə çağırdığımız interfeys
SimpleInterface
yalnız bir metodu elan edir
performAction
. İnterfeyslər və siniflər arasındakı əsas fərq ondan ibarətdir ki, interfeyslər kontaktın nə olması lazım olduğunu göstərir (onlar bir metodu elan edirlər), lakin onların həyata keçirilməsini təmin etmirlər. Bununla belə, Java-da interfeyslər daha mürəkkəb ola bilər: onlara iç-içə interfeyslər, siniflər, saylar, annotasiyalar və sabitlər daxil ola bilər. Misal üçün:
package com.javacodegeeks.advanced.design;
public interface InterfaceWithDefinitions {
String CONSTANT = "CONSTANT";
enum InnerEnum {
E1, E2;
}
class InnerClass {
}
interface InnerInterface {
void performInnerAction();
}
void performAction();
}
Bu daha mürəkkəb nümunədə, interfeyslərin qeyd-şərtsiz daxili konstruksiyalara və Java kompilyatorunun tətbiq etdiyi metod bəyanlarına tətbiq etdiyi bir neçə məhdudiyyət var. Əvvəla, açıq şəkildə elan edilməsə belə, interfeysdəki hər bir metod bəyannaməsi açıqdır
( və yalnız ictimai ola bilər). Beləliklə, aşağıdakı metod bəyannamələri ekvivalentdir:
public void performAction();
void performAction();
Qeyd etmək lazımdır ki, interfeysdəki hər bir metod
mücərrəd elan edilir və hətta bu metod bəyannamələri də ekvivalentdir:
public abstract void performAction();
public void performAction();
void performAction();
Elan edilmiş daimi sahələrə gəldikdə, onlar
ictimai olmaqla yanaşı , həm də dolayısı ilə
statikdir və
yekun olaraq qeyd olunur . Beləliklə, aşağıdakı bəyannamələr də ekvivalentdir:
String CONSTANT = "CONSTANT";
public static final String CONSTANT = "CONSTANT";
Nəhayət, iç-içə siniflər, interfeyslər və ya saylar ictimai olmaqla yanaşı , həm də dolayısı ilə
statik elan edilir . Məsələn, bu bəyannamələr də aşağıdakılara bərabərdir:
class InnerClass {
}
static class InnerClass {
}
Seçdiyiniz üslub şəxsi seçimdir, lakin interfeyslərin bu sadə xüsusiyyətlərini bilmək sizi lazımsız yazmaqdan xilas edə bilər.
3. İnterfeys markeri
Marker interfeysi metodları və ya digər iç içə konstruksiyaları olmayan xüsusi bir interfeys növüdür. Java kitabxanası onu necə müəyyənləşdirir:
public interface Cloneable {
}
İnterfeys markerləri özlüyündə müqavilələr deyil, lakin müəyyən xüsusiyyəti siniflə "qoşmaq" və ya "əlaqələndirmək" üçün bir qədər faydalı texnikadır. Məsələn,
Cloneable ilə əlaqədar olaraq , sinif klonlaşdırıla bilən kimi qeyd olunur, lakin bunun həyata keçirilə biləcəyi və ya edilməli olduğu yol interfeysin bir hissəsi deyil. İnterfeys markerinin çox məşhur və geniş istifadə olunan başqa bir nümunəsi
Serializable
:
public interface Serializable {
}
Bu interfeys sinfi seriallaşdırma və sıradan çıxarma üçün uyğun olaraq qeyd edir və yenə də bunun necə həyata keçirilə biləcəyini və ya edilməli olduğunu göstərmir. İnterfeys markerlərinin obyekt yönümlü proqramlaşdırmada öz yeri var, baxmayaraq ki, onlar interfeysin müqavilə olması kimi əsas məqsədini təmin etmir.
4. FUNKSİONAL İNTERFESYONLAR, DEFORT ÜSULLAR VƏ STATİK ÜSULLAR
Java 8-in buraxılışından bəri interfeyslər çox maraqlı yeni xüsusiyyətlər qazanmışdır: statik metodlar, standart metodlar və lambdalardan avtomatik çevrilmə (funksional interfeyslər). İnterfeyslər bölməsində biz Java-dakı interfeyslərin yalnız metodları elan edə biləcəyini, lakin onların həyata keçirilməsini təmin etmədiyini vurğuladıq. Defolt metodla hər şey fərqlidir: interfeys
standart açar sözlə metodu qeyd edə və bunun üçün tətbiq təmin edə bilər. Misal üçün:
package com.javacodegeeks.advanced.design;
public interface InterfaceWithDefaultMethods {
void performAction();
default void performDefaulAction() {
}
}
Nümunə səviyyəsində olduğundan, defolt metodlar hər bir interfeys tətbiqi ilə ləğv edilə bilər, lakin indi interfeyslərə
statik metodlar da daxil ola bilər, məsələn: paket com.javacodegeeks.advanced.design;
public interface InterfaceWithDefaultMethods {
static void createAction() {
}
}
Demək olar ki, interfeysdə tətbiqin təmin edilməsi müqavilə proqramlaşdırmasının bütün məqsədini məğlub edir. Lakin bu xüsusiyyətlərin Java dilinə daxil olmasının bir çox səbəbi var və nə qədər faydalı və ya çaşdırıcı olsalar da, onlar sizin və istifadəniz üçün mövcuddur. Funksional interfeyslər fərqli bir hekayədir və dilə çox faydalı əlavələr olduğunu sübut etdi. Əsasən, funksional interfeys, yalnız bir mücərrəd metodun elan edildiyi interfeysdir.
Runnable
Standart kitabxana interfeysi bu konsepsiyanın çox yaxşı nümunəsidir.
@FunctionalInterface
public interface Runnable {
void run();
}
Java kompilyatoru funksional interfeyslərə fərqli yanaşır və məntiqli olduğu yerdə lambda funksiyasını funksional interfeys tətbiqinə çevirə bilər. Aşağıdakı funksiya təsvirini nəzərdən keçirək:
public void runMe( final Runnable r ) {
r.run();
}
Java 7 və daha aşağı versiyalarda bu funksiyanı çağırmaq üçün interfeysin tətbiqi təmin edilməlidir
Runnable
(məsələn, anonim siniflərdən istifadə etməklə), lakin Java 8-də lambda sintaksisindən istifadə edərək run() metodunun həyata keçirilməsini təmin etmək kifayətdir:
runMe( () -> System.out.println( "Run!" ) );
Bundan əlavə,
@FunctionalInterface annotasiyası (annotasiyalar təlimatın 5-ci hissəsində ətraflı təsvir olunacaq) göstəriş verir ki, tərtibçi interfeysdə yalnız bir mücərrəd metoddan ibarət olub-olmadığını yoxlaya bilər, ona görə də gələcəkdə interfeysə edilən hər hansı dəyişiklik bu fərziyyəni pozmayacaq. .
5. REFERAT DƏRSLƏR
Java dili tərəfindən dəstəklənən digər maraqlı konsepsiya abstrakt siniflər anlayışıdır. Mücərrəd siniflər Java 7-dəki interfeyslərə bir qədər bənzəyir və Java 8-dəki standart metod interfeysinə çox yaxındır. Adi siniflərdən fərqli olaraq, mücərrəd sinif yaradıla bilməz, lakin o, alt siniflərə bölünə bilər (daha ətraflı məlumat üçün Miras bölməsinə baxın). Daha da əhəmiyyətlisi, mücərrəd siniflər mücərrəd metodları ehtiva edə bilər: interfeys kimi tətbiqi olmayan xüsusi bir metod növü. Misal üçün:
package com.javacodegeeks.advanced.design;
public abstract class SimpleAbstractClass {
public void performAction() {
}
public abstract void performAnotherAction();
}
Bu nümunədə sinif
mücərrədSimpleAbstractClass
elan edilir və elan edilmiş bir abstrakt metoddan ibarətdir. Abstrakt siniflər çox faydalıdır; həyata keçirmə təfərrüatlarının əksəriyyəti və ya hətta bəzi hissələri bir çox alt siniflər arasında paylaşıla bilər. Nə olursa olsun, onlar hələ də qapını açıq qoyurlar və mücərrəd üsullardan istifadə edərək hər bir alt sinifə xas olan davranışı fərdiləşdirməyə imkan verirlər. Qeyd etmək lazımdır ki, yalnız
ictimai bəyannamələri ehtiva edə bilən interfeyslərdən fərqli olaraq, mücərrəd siniflər mücərrəd metodun görünməsinə nəzarət etmək üçün əlçatanlıq qaydalarının tam gücündən istifadə edə bilər.
6. TECILI DERSLER
Dəyişməzlik hal-hazırda proqram təminatının hazırlanmasında getdikcə daha çox əhəmiyyət kəsb edir. Çoxnüvəli sistemlərin yüksəlişi məlumat mübadiləsi və paralellik ilə bağlı bir çox məsələləri gündəmə gətirib. Ancaq bir problem mütləq ortaya çıxdı: dəyişkən vəziyyətin az olması (və ya hətta olmaması) sistem haqqında daha yaxşı genişlənməyə (miqyaslılığa) və asan əsaslandırmaya gətirib çıxarır. Təəssüf ki, Java dili sinfin dəyişməzliyi üçün layiqli dəstək vermir. Bununla belə, texnikaların kombinasiyasından istifadə etməklə, dəyişməz sinifləri dizayn etmək mümkün olur. İlk növbədə, sinfin bütün sahələri yekun olmalıdır (
yekun olaraq qeyd olunur ). Bu yaxşı başlanğıcdır, lakin heç bir zəmanət vermir.
package com.javacodegeeks.advanced.design;
import java.util.Collection;
public class ImmutableClass {
private final long id;
private final String[] arrayOfStrings;
private final Collection<String> collectionOfString;
}
İkincisi, düzgün inisializasiyanı təmin edin: əgər sahə kolleksiyaya və ya massiləyə istinaddırsa, bu sahələri birbaşa konstruktor arqumentlərindən təyin etməyin, əvəzinə surətləri çıxarın. Bu, kolleksiyanın və ya massivin vəziyyətinin ondan kənarda dəyişdirilməməsini təmin edəcək.
public ImmutableClass( final long id, final String[] arrayOfStrings,
final Collection<String> collectionOfString) {
this.id = id;
this.arrayOfStrings = Arrays.copyOf( arrayOfStrings, arrayOfStrings.length );
this.collectionOfString = new ArrayList<>( collectionOfString );
}
Və nəhayət, düzgün girişin təmin edilməsi (alıcılar). Kolleksiyalar üçün dəyişməzlik sarğı kimi təqdim edilməlidir
Collections.unmodifiableXxx
: Massivlərlə həqiqi dəyişməzliyi təmin etməyin yeganə yolu massivə istinadı qaytarmaq əvəzinə surəti təqdim etməkdir. Bu, praktiki baxımdan məqbul olmaya bilər, çünki bu, massivin ölçüsündən çox asılıdır və zibil kollektoruna böyük təzyiq göstərə bilər.
public String[] getArrayOfStrings() {
return Arrays.copyOf( arrayOfStrings, arrayOfStrings.length );
}
Hətta bu kiçik nümunə də yaxşı bir fikir verir ki, dəyişməzlik hələ Java-da birinci dərəcəli vətəndaş deyil. Dəyişməz sinfin başqa sinfin obyektinə istinad edən sahəsi varsa, işlər çətinləşə bilər. Həmin siniflər də dəyişməz olmalıdır, lakin bunu təmin etmək üçün heç bir yol yoxdur. FindBugs və PMD kimi bir neçə layiqli Java mənbə kodu analizatorları var ki, bunlar kodunuzu yoxlamaq və ümumi Java proqramlaşdırma qüsurlarını göstərməklə çox kömək edə bilər. Bu alətlər istənilən Java tərtibatçısının əla dostlarıdır.
7. ANONİM DERSLER
Java 8-dən əvvəlki dövrdə, anonim siniflər siniflərin tez müəyyən edilməsini və dərhal yaradılmasını təmin etmək üçün yeganə yol idi. Anonim siniflərin məqsədi qazanc səviyyəsini azaltmaq və sinifləri rekord kimi təqdim etmək üçün qısa və asan bir yol təqdim etmək idi. Gəlin Java-da yeni mövzu yaratmaq üçün tipik köhnə üsula nəzər salaq:
package com.javacodegeeks.advanced.design;
public class AnonymousClass {
public static void main( String[] args ) {
new Thread(
new Runnable() {
@Override
public void run() {
}
}
).start();
}
}
Bu nümunədə interfeysin həyata keçirilməsi
Runnable
anonim sinif kimi dərhal təmin edilir. Anonim siniflərlə bağlı bəzi məhdudiyyətlər olsa da, onlardan istifadənin əsas çatışmazlıqları Java-nın bir dil olaraq məcbur etdiyi yüksək ətraflı konstruksiya sintaksisidir. Heç nə etməyən sadəcə anonim sinif belə hər yazılan zaman ən azı 5 sətir kod tələb edir.
new Runnable() {
@Override
public void run() {
}
}
Xoşbəxtlikdən, Java 8, lambda və funksional interfeyslərlə bütün bu stereotiplər tezliklə yox olacaq, nəhayət Java kodunun yazılması həqiqətən də qısa görünəcək.
package com.javacodegeeks.advanced.design;
public class AnonymousClass {
public static void main( String[] args ) {
new Thread( () -> { } ).start();
}
}
8. GÖRÜNÜRLÜK
Biz artıq dərsliyin 1-ci hissəsində Java-da görünmə və əlçatanlıq qaydaları haqqında bir az danışdıq. Bu hissədə biz bu mövzuya yenidən baxacağıq, lakin alt təsnifat kontekstində.
![Siniflərin və interfeyslərin dizaynı (Məqalənin tərcüməsi) - 2]()
Fərqli səviyyələrdə görünmə siniflərə digər sinifləri və ya interfeysləri (məsələn, onlar müxtəlif paketlərdədirsə və ya bir-biri ilə iç-içədirsə) görməyə və ya alt siniflərə valideynlərinin metodlarını, konstruktorlarını və sahələrini görməyə və onlara daxil olmağa imkan verir və ya qarşısını alır. Növbəti bölmədə, miras, biz bunu hərəkətdə görəcəyik.
9. MİRAS
Varislik, münasibətlər sinfinin qurulması üçün əsas rolunu oynayan obyekt yönümlü proqramlaşdırmanın əsas anlayışlarından biridir. Görünüş və əlçatanlıq qaydaları ilə birlikdə miras sinifləri genişləndirilə və saxlanıla bilən bir iyerarxiya şəklində tərtib etməyə imkan verir. Konseptual səviyyədə Java-da varislik alt sinifdən və ana siniflə birlikdə
genişləndirir açar sözündən istifadə etməklə həyata keçirilir. Alt sinif ana sinfin bütün ictimai və qorunan elementlərini miras alır. Bundan əlavə, hər ikisi (alt sinif və sinif) eyni paketdədirsə, alt sinif öz ana sinifinin paket-özəl elementlərini miras alır. Bununla yanaşı, nə dizayn etməyə çalışmağınızdan asılı olmayaraq, bir sinfin ictimaiyyətə və ya alt siniflərinə təqdim etdiyi minimum metodlar dəstinə sadiq qalmaq çox vacibdir. Məsələn, görünmə səviyyələrindəki fərqi və onların təsirlərini nümayiş etdirmək üçün sinfə
Parent
və onun alt sinfinə baxaq .
Child
package com.javacodegeeks.advanced.design;
public class Parent {
public static final String CONSTANT = "Constant";
private String privateField;
protected String protectedField;
private class PrivateClass {
}
protected interface ProtectedInterface {
}
public void publicAction() {
}
protected void protectedAction() {
}
private void privateAction() {
}
void packageAction() {
}
}
package com.javacodegeeks.advanced.design;
public class Child extends Parent implements Parent.ProtectedInterface {
@Override
protected void protectedAction() {
super.protectedAction();
}
@Override
void packageAction() {
}
public void childAction() {
this.protectedField = "value";
}
}
Varislik özlüyündə çox böyük bir mövzudur, Java-ya xas olan çoxlu incə detallara malikdir. Bununla belə, riayət etmək asan olan və sinif iyerarxiyasının qısalığını saxlamaq üçün uzun bir yol keçə bilən bir neçə qayda var. Java-da hər bir alt sinif, son elan edilmədiyi təqdirdə, valideyninin hər hansı irsi üsullarını ləğv edə bilər. Bununla belə, metodu ləğv edilmiş kimi qeyd etmək üçün xüsusi sintaksis və ya açar söz yoxdur, bu da çaşqınlığa səbəb ola bilər.
Buna görə @Override annotasiyası təqdim edildi : məqsədiniz irsi metodu ləğv etmək olduqda, onu qısa şəkildə göstərmək üçün
@Override annotasiyasından istifadə edin . Java tərtibatçılarının dizaynda daim qarşılaşdıqları digər dilemma, interfeyslərin həyata keçirilməsinə qarşı sinif iyerarxiyalarının (konkret və ya abstrakt siniflərlə) qurulmasıdır. Mümkün olduqda siniflər və ya abstrakt siniflər üzərində interfeyslərə üstünlük verməyi şiddətlə tövsiyə edirik. İnterfeyslər daha yüngüldür, sınaqdan keçirmək və saxlamaq daha asandır, həmçinin tətbiq dəyişikliklərinin yan təsirlərini minimuma endirir. Java standart kitabxanasında proxy sinifləri yaratmaq kimi bir çox qabaqcıl proqramlaşdırma texnikası əsasən interfeyslərə əsaslanır.
10. ÇOXLU VİRASLIQ
C++ və bəzi digər dillərdən fərqli olaraq, Java çoxlu varisliyi dəstəkləmir: Java-da hər bir sinfin yalnız bir birbaşa valideyni ola bilər (sinf
Object
iyerarxiyanın yuxarısında yerləşir). Bununla belə, bir sinif birdən çox interfeys həyata keçirə bilər və beləliklə, interfeysin yığılması Java-da çoxsaylı miras əldə etmək (və ya simulyasiya etmək) üçün yeganə yoldur.
package com.javacodegeeks.advanced.design;
public class MultipleInterfaces implements Runnable, AutoCloseable {
@Override
public void run() {
}
@Override
public void close() throws Exception {
}
}
Çoxsaylı interfeyslərin tətbiqi əslində kifayət qədər güclüdür, lakin tez-tez tətbiqetmədən dəfələrlə istifadə etmək ehtiyacı Java-nın çoxsaylı irsiyyət dəstəyinin çatışmazlığını aradan qaldırmaq üçün bir yol kimi dərin sinif iyerarxiyasına gətirib çıxarır.
public class A implements Runnable {
@Override
public void run() {
}
}
public class B extends A implements AutoCloseable {
@Override
public void close() throws Exception {
}
}
public class C extends B implements Readable {
@Override
public int read(java.nio.CharBuffer cb) throws IOException {
}
}
Və s... Java 8-in son buraxılışı standart metod inyeksiyası ilə bağlı problemi bir qədər həll edir. Defolt üsullara görə interfeyslər əslində təkcə müqavilə deyil, həm də həyata keçirməyi təmin edir. Buna görə də, bu interfeysləri həyata keçirən siniflər də bu həyata keçirilən metodları avtomatik olaraq miras alacaqlar. Misal üçün:
package com.javacodegeeks.advanced.design;
public interface DefaultMethods extends Runnable, AutoCloseable {
@Override
default void run() {
}
@Override
default void close() throws Exception {
}
}
public class C implements DefaultMethods, Readable {
@Override
public int read(java.nio.CharBuffer cb) throws IOException {
}
}
Unutmayın ki, çoxsaylı miras çox güclü, lakin eyni zamanda təhlükəli bir vasitədir. Məşhur “Ölüm almazı” problemi tez-tez çoxlu mirasın həyata keçirilməsində əsas qüsur kimi qeyd edilir və tərtibatçıları sinif iyerarxiyalarını çox diqqətlə tərtib etməyə məcbur edir. Təəssüf ki, standart metodlara malik Java 8 interfeysləri də bu qüsurların qurbanı olur.
interface A {
default void performAction() {
}
}
interface B extends A {
@Override
default void performAction() {
}
}
interface C extends A {
@Override
default void performAction() {
}
}
Məsələn, aşağıdakı kod parçası tərtib edilməyəcək:
interface E extends B, C {
}
Bu nöqtədə demək ədalətli olar ki, Java bir dil olaraq həmişə obyekt yönümlü proqramlaşdırmanın künc hallardan qaçmağa çalışıb, lakin dil inkişaf etdikcə bu halların bəziləri birdən-birə görünməyə başlayıb.
11. İRSƏ VƏ TƏRKİB
Xoşbəxtlikdən, miras sinifinizi dizayn etməyin yeganə yolu deyil. Bir çox tərtibatçının mirasdan daha yaxşı olduğuna inandığı başqa bir alternativ kompozisiyadır. İdeya çox sadədir: siniflərin iyerarxiyasını yaratmaq əvəzinə, onları başqa siniflərdən təşkil etmək lazımdır. Bu misala baxaq:
interface E extends B, C {
}
Sinif
Vehicle
mühərrikdən və təkərlərdən (əlavə olaraq sadəlik üçün kənara qoyulmuş bir çox digər hissələrdən) ibarətdir. Bununla belə, bir sinifin də bir mühərrik olduğunu söyləmək olar
Vehicle
, ona görə də mirasdan istifadə edərək dizayn edilə bilər.
public class Vehicle extends Engine {
private Wheels[] wheels;
}
Hansı dizayn həlli düzgün olardı? Ümumi əsas təlimatlar IS-A (is) və HAS-A (tərkib edir) prinsipləri kimi tanınır. IS-A irsiyyət əlaqəsidir: alt sinif həm də ana sinfin sinif spesifikasiyasına və ana sinfin variasiyasına cavab verir. alt sinif) öz anasını genişləndirir. Bir obyektin digərini genişləndirib-genişləndirmədiyini bilmək istəyirsinizsə, uyğunluq testi edin - IS -A (is).") Buna görə də, HAS-A kompozisiya əlaqəsidir: sinif əksər hallarda bir sıra səbəblərə görə HAS-A prinsipi IS-A-dan daha yaxşı işləyən obyektə sahibdir (və ya ehtiva edir):
- Dizayn daha çevikdir;
- Model daha stabildir, çünki dəyişiklik sinif iyerarxiyası vasitəsilə yayılmır;
- Bir sinif və onun tərkibi bir valideyn və onun alt sinfini sıx birləşdirən kompozisiya ilə müqayisədə sərbəst şəkildə bağlıdır.
- Bir sinifdə məntiqi düşüncə qatarı daha sadədir, çünki onun bütün asılılıqları bir yerdə daxil edilir.
Nə olursa olsun, miras öz yeri var və bir sıra mövcud dizayn problemlərini müxtəlif yollarla həll edir, buna görə də laqeyd yanaşmaq olmaz. Obyekt yönümlü modelinizi tərtib edərkən bu iki alternativi nəzərə alın.
12. KAPSULYASİYA.
Obyekt yönümlü proqramlaşdırmada inkapsulyasiya konsepsiyası bütün icra detallarını (məsələn, iş rejimi, daxili üsullar və s.) xarici dünyadan gizlətməkdir. İnkapsulyasiyanın üstünlükləri davamlılıq və dəyişdirmə asanlığıdır. Sinfin daxili tətbiqi gizlidir, sinif məlumatları ilə işləmək yalnız sinfin ictimai metodları vasitəsilə baş verir (bir çox insanın istifadə etdiyi bir kitabxana və ya çərçivə hazırlayırsanız, əsl problem). Java-da inkapsulyasiya görünmə və əlçatanlıq qaydaları vasitəsilə əldə edilir. Java-da sahələri heç vaxt birbaşa, yalnız alıcılar və tənzimləyicilər vasitəsilə ifşa etmək ən yaxşı təcrübə hesab olunur (sahələr yekun olaraq qeyd olunmayıbsa). Misal üçün:
package com.javacodegeeks.advanced.design;
public class Encapsulation {
private final String email;
private String address;
public Encapsulation( final String email ) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
}
Bu nümunə Java dilində
JavaBeans adlanan şeyi xatırladır : standart Java sinifləri bir sıra konvensiyalara uyğun olaraq yazılır, bunlardan biri sahələrə yalnız getter və setter metodlarından istifadə etməklə daxil olmağa imkan verir. Vərəsəlik bölməsində artıq vurğuladığımız kimi, inkapsulyasiya prinsiplərindən istifadə edərək, həmişə sinifdə minimum reklam müqaviləsinə əməl edin. İctimai olmamalı olan hər şey şəxsi (və ya həll etdiyiniz problemdən asılı olaraq qorunan/paket özəl) olmalıdır. Bu, dəyişikliklər etmədən (və ya ən azı onları minimuma endirmədən) dizayn azadlığı verməklə uzun müddətdə öz bəhrəsini verəcəkdir.
13. YEKUN DƏRSLƏR VƏ METODLAR
Java-da bir sinfin başqa bir sinfin alt sinfinə çevrilməsinin qarşısını almağın bir yolu var: digər sinif final elan edilməlidir.
package com.javacodegeeks.advanced.design;
public final class FinalClass {
}
Metod elanında eyni
son açar söz alt siniflərin metodu ləğv etməsinə mane olur.
package com.javacodegeeks.advanced.design;
public class FinalMethod {
public final void performAction() {
}
}
Bir sinfin və ya metodların yekun olub-olmamasına qərar vermək üçün ümumi qaydalar yoxdur. Yekun siniflər və metodlar genişlənmə qabiliyyətini məhdudlaşdırır və bir sinfin miras alınmalı olub-olmaması və ya metodun gələcəkdə ləğv edilməli olub-olmaması barədə əvvəlcədən düşünmək çox çətindir. Bu, kitabxana tərtibatçıları üçün xüsusilə vacibdir, çünki bu kimi dizayn qərarları kitabxananın tətbiqini əhəmiyyətli dərəcədə məhdudlaşdıra bilər. Java Standart Kitabxanasında son siniflərin bir neçə nümunəsi var, ən məşhuru String sinfidir. Erkən mərhələdə, bu qərar tərtibatçıların sətir tətbiq etmək üçün öz, "daha yaxşı" həllini tapmaq cəhdlərinin qarşısını almaq üçün qəbul edildi.
14. SONRAKİ NƏ VAR
Dərsin bu hissəsində biz Java-da obyekt yönümlü proqramlaşdırma anlayışlarını əhatə etdik. Biz həmçinin müqavilə proqramlaşdırmasına qısa nəzər saldıq, bəzi funksional anlayışlara toxunduq və dilin zamanla necə inkişaf etdiyini gördük. Dərsin növbəti hissəsində biz generiklərlə və onların proqramlaşdırmada tip təhlükəsizliyinə yanaşma tərzimizi necə dəyişdirdiyi ilə tanış olacağıq.
15. MƏNBƏ KODU YÜKLƏ
Mənbəni buradan yükləyə bilərsiniz -
advanced-java-part-3 Mənbə:
Dərsləri necə tərtib etmək olar
GO TO FULL VERSION