![translation](https://cdn.durumis.com/common/trans.png)
Dit is een door AI vertaalde post.
[Objecten] Hoofdstuk 2. Objectgeoriënteerde programmering
- Taal van de tekst: Koreaans
- •
-
Referentieland: Alle landen
- •
- Informatietechnologie
Selecteer taal
Samengevat door durumis AI
- Het document beschrijft de objectgeoriënteerde programmeringsaanpak voor het implementeren van een filmreserveringssysteem, introducerend de concepten van samenwerking, objecten en klassen, en benadrukt de structuur van het programma die de domeinstructuur volgt.
- Het document presenteert in het bijzonder hoe de autonomie van objecten en inkapseling externe interferentie kunnen verminderen, en hoe het scheiden van interfaces en implementaties de vrijheid van programmeurs waarborgt.
- Het document beschrijft ook hoe u flexibele en uitbreidbare code kunt schrijven door middel van samenwerking, overerving en polymorfisme voor het berekenen van kortingstarieven, en benadrukt het belang van abstractie en de voordelen van compositie voor codeherbruik.
Filmreserveringsysteem
Vereisten bekijken
- We willen een online filmreserveringsysteem implementeren.
- Een film vertegenwoordigt de basisinformatie over een film.
- Titel, speelduur, prijsinformatie, etc.
- Een screening vertegenwoordigt het daadwerkelijke evenement waarbij het publiek een film bekijkt.
- Datum, tijd, volgnummer, etc.
- Mensen reserveren films, maar eigenlijk reserveren ze een specifiekescreeningvan een film.
- Kortingvoorwaarden
- Of er korting op de prijs is
- Volgordevoorwaarde: gebruik het volgnummer van de screening om te bepalen of er korting is.
- Tijdsvoorwaarde: gebruik de begintijd van de screening om te bepalen of er korting is.
- Kortingbeleid
- Stel de kortingsprijs vast.
- Korting op basis van bedrag: trek een vast bedrag af van de reserveringskosten.
- Korting op basis van percentage: trek een percentage af van de reguliere prijs.
- Per film kan er één kortingbeleid worden toegewezen, of helemaal geen. Kortingvoorwaarden kunnen worden gecombineerd.
- Als er kortingbeleid van toepassing is, maar de voorwaarden niet worden voldaan, of als er geen kortingbeleid van toepassing is, wordt er geen korting toegepast.
Naar objectgeoriënteerd programmeren
Samenwerking, objecten, klassen
- Objectgeoriënteerd betekent objecten gericht.
- Zodra je de klassen hebt bepaald, moet je niet nadenken over welke attributen en methoden er in de klassen moeten zitten.
- Je moet bepalen welke objecten welke status en gedrag hebben.
- Je moet objecten niet als onafhankelijke entiteiten zien, maar als onderdeel van een samenwerkende gemeenschap.
Programmastructuur die de structuur van het domein volgt
- Het domein is het gebied waar de gebruiker het programma gebruikt om een probleem op te lossen.
- Over het algemeen moeten de namen van klassen overeenkomen met of op zijn minst lijken op de namen van de corresponderende domeinconcepten.
- De relaties tussen klassen moeten zo veel mogelijk lijken op de relaties tussen domeinconcepten om de structuur van het programma te vereenvoudigen en te voorspellen.
Klassen implementeren
- Een klasse is verdeeld in intern en extern. Om een goede klasse te ontwerpen moet je bepalen welke delen openbaar worden gemaakt en welke delen worden verborgen.
- Maak de attributen van het object privé en openbaar de methoden die nodig zijn om de interne status te wijzigen.
- Het onderscheiden van de binnen- en buitenkant van een klasse zorgt ervoor dat de autonomie van het object wordt gewaarborgd, waardoor de programmeur meer vrijheid krijgt bij de implementatie.
Autonome objecten
- Objecten moeten autonome objecten zijn met een status en gedrag.
- Het samenvoegen van data en functionaliteit binnen een object wordt encapsulatie genoemd.
- Door toegang te beperken, wordt externe inmenging verminderd, waardoor het object zijn eigen gedrag kan bepalen.
- Het principe van scheiding van interface en implementatie is een belangrijk principe om te volgen bij
objectgeoriënteerd programmeren.
- Openbare interface: het deel dat van buitenaf toegankelijk is
- Implementatie: het deel dat alleen van binnenuit toegankelijk is
Vrijheid voor de programmeur
- De rol van de programmeur is verdeeld in klasse-schrijvers en clientprogrammeurs.
- Klasse-schrijvers voegen nieuwe datatype toe.
- Clientprogrammeurs gebruiken de datatype die door de klasse-schrijver zijn toegevoegd.
- Implementatieverborgenheid
- Klasse-schrijvers kunnen de interne implementatie verbergen door alleen het benodigde deel aan de clientprogrammeur te presenteren.
- Clientprogrammeurs hoeven alleen de interface te kennen, wat de hoeveelheid kennis die ze nodig hebben vermindert.
Een samenwerkende gemeenschap van objecten
- Wanneer je geld wilt uitdrukken, is het beter om het in te pakken in een object zoals Money, in plaats van gewoon een variabele van het type Long te declareren. Door objecten te gebruiken, wordt de betekenis beter overgebracht en kunnen herhaalde bewerkingen op één plek worden uitgevoerd.
- De interactie tussen objecten om een functie in het systeem te implementeren wordt samenwerking genoemd.
Een kort verhaal over samenwerking
- De enige manier waarop een object met een ander object kan communiceren is door berichten te verzenden of te ontvangen.
- Een methode wordt gebruikt om een ontvangen bericht te verwerken.
- Het onderscheiden van berichten en methoden is belangrijk, omdat dit het startpunt is voor het concept polymorfisme.
Kortingsprijs berekenen
Samenwerking starten om de kortingsprijs te berekenen
- De klasse Movie bevat geen gedetailleerde logica met betrekking tot het kortingbeleid, maar delegeert deze naar de interface DiscountPolicy. Overerving, polymorfisme en abstractie zijn erg belangrijk.
Kortingbeleid en kortingvoorwaarden
Overerving en polymorfisme
Afhankelijkheid tijdens compileertijd en runtime
- De afhankelijkheid van de code en de afhankelijkheid tijdens runtime kunnen verschillen.
- Hoe meer de afhankelijkheden verschillen, hoe moeilijker het is om de code te begrijpen, maar hoe flexibeler en uitbreidbaar de code wordt.
Programmeren op basis van verschillen
- Met overerving kun je snel en gemakkelijk nieuwe klassen toevoegen op basis van bestaande klassen, en de implementatie van de bovenliggende klasse hergebruiken.
- De techniek om nieuwe klassen te maken door alleen het verschil met de bovenliggende klasse toe te voegen wordt programmeren op basis van verschillen genoemd.
Overerving en interfaces
- Overerving zorgt ervoor dat de onderliggende klasse alle interfaces overneemt van de bovenliggende klasse.
- Een interface definieert de lijst met berichten die een object kan begrijpen.
public class Movie {
public Money calculateMovieFee(Screening screening) {
return fee.minus(discountPolicy.calculateDiscountAmount(screening));
}
- Movie stuurt het bericht calculateDiscountAmount naar DiscountPolicy. Movie maakt zich geen zorgen over welke klasse-instantie reageert, zolang het antwoord succesvol is.
- Dus zowel AmountDiscountPolicy als PercentDiscountPolicy kunnen DiscountPolicy vervangen om met Movie samen te werken.
- Dit proces waarbij de onderliggende klasse de bovenliggende klasse vervangt wordt upcasting genoemd. Dit omdat het lijkt alsof de onderliggende klasse automatisch wordt gecast naar de bovenliggende klasse.
Polymorfisme
- Polymorfisme is het vermogen om op verschillende manieren te reageren op hetzelfde bericht, afhankelijk van het
type object.
- Movie stuurt hetzelfde bericht, maar welke methode daadwerkelijk wordt uitgevoerd hangt af van de klasse van het object dat het bericht ontvangt.
- Polymorfisme is gebaseerd op het feit dat de code tijdens compileertijd en runtime van de code verschillend kan zijn.
- Polymorfisme bepaalt de uit te voeren methode tijdens runtime, vandaar de term late binding of dynamische binding.
Interfaces en polymorfisme
- Als je alleen de interface wilt delen en de implementatie niet hoeft te delen, gebruik dan een interface in plaats van een abstracte klasse.
Abstractie en flexibiliteit
De kracht van abstractie
- Voordelen van abstractie
- Als je alleen naar de abstractielaag kijkt, kun je het beleid van de vereisten op een hoger niveau beschrijven.
- Het ontwerp wordt flexibeler.
Flexibel ontwerp
- Abstractie voorkomt dat het ontwerp wordt gekoppeld aan specifieke omstandigheden, wat zorgt voor een flexibel ontwerp.
Abstracte klassen en interface trade-offs
public abstract class DiscountPolicy {
private List conditions;
public DiscountPolicy(DiscountCondition... conditions) {
this.conditions = Arrays.asList(conditions);
}
public Money calculateDiscountAmount(Screening screening) {
for (DiscountCondition condition : conditions) {
if (condition.isSatisfiedBy(screening)) {
return getDiscountAmount(screening);
}
}
return Money.ZERO;
}
abstract protected Money getDiscountAmount(Screening screening);
}
public class NoneDiscountPolicy extends DiscountPolicy {
@Override
protected Money getDiscountAmount(Screening screening) {
return Money.ZERO;
}
- Op dit moment is NoneDiscountPolicy eigenlijk niet nodig, omdat calculateDiscountAmount() van DiscountPolicy al 0 retourneert als er geen kortingvoorwaarden zijn. Maar we hebben het toegevoegd omdat gebruikers een None-beleid zonder kortingbeleid als argument voor Movie moeten invoegen.
- Daarom is de klasse NoneDiscountPolicy verwarrend. De volgende aanpassing maakt het makkelijker te begrijpen.
public interface DiscountPolicy {
Money calculdateDiscountAmount(Screening screening);
}
public abstract class DefaultDiscountPolicy implements DiscountPolicy {
private List conditions;
public DefaultDiscountPolicy(DiscountCondition... conditions) {
this.conditions = Arrays.asList(conditions);
}
public Money calculateDiscountAmount(Screening screening) {
for (DiscountCondition condition : conditions) {
if (condition.isSatisfiedBy(screening)) {
return getDiscountAmount(screening);
}
}
return Money.ZERO;
}
abstract protected Money getDiscountAmount(Screening screening);
}
public class NoneDiscountPolicy implements DiscountPolicy {
@Override
public Money calculateDiscountAmount(Screening screening) {
return Money.ZERO;
}
}
public class PercentDiscountPolicy extends DefaultDiscountPolicy {
private double percent;
public PercentDiscountPolicy(double percent, DiscountCondition... conditions) {
super(conditions);
this.percent = percent;
}
@Override
protected Money getDiscountAmount(Screening screening) {
return screening.getMovieFee().times(percent);
}
}
public class AmountDiscountPolicy extends DefaultDiscountPolicy {
private Money discountAmount;
public AmountDiscountPolicy(Money discountAmount, DiscountCondition... conditions) {
super(conditions);
this.discountAmount = discountAmount;
}
@Override
protected Money getDiscountAmount(Screening screening) {
return discountAmount;
}
- Maak DiscountPolicy een interface, met de implementaties NoneDiscountPolicy en DefaultDiscountPolicy, die een algemeen kortingbeleid vertegenwoordigt.
- Het toevoegen van een interface voor alleen NoneDiscountPolicy lijkt misschien inefficiënt in vergelijking met de toename van de complexiteit.
- Het is belangrijk om je te realiseren dat alles wat met implementatie te maken heeft een trade-off is. Dat wil zeggen, alle code die je schrijft moet een goede reden hebben.
Code hergebruik
- Overerving kan worden gebruikt om code te hergebruiken.
- Maar het is beter om compositie te gebruiken dan overerving om code te hergebruiken.
- De huidige manier waarop Movie code hergebruikt van DiscountPolicy is compositie.
- Als Movie een bovenliggende klasse zou zijn en we deze opsplitsen in AmountDiscountMovie en PercentDiscountMovie, dan zouden we overerving gebruiken.
Overerving
- Nadelen van overerving
- Schendt encapsulatie.
- Je moet de interne structuur van de bovenliggende klasse kennen.
- De kans is groot dat de onderliggende klasse ook moet worden aangepast als de bovenliggende klasse wordt aangepast.
- Maakt het ontwerp minder flexibel.
- De relatie tussen bovenliggende klasse en onderliggende klasse wordt tijdens compileertijd bepaald.
- Het is niet mogelijk om het type object tijdens runtime te wijzigen.
- Maar met compositie kan de gebruiker tijdens runtime een nieuw exemplaar vervangen door een methode zoals changeDiscountPolicy().
- Schendt encapsulatie.
Compositie
- De techniek om code te hergebruiken door middel van berichten die zijn gedefinieerd in een interface wordt compositie genoemd.
- Het maakt encapsulatie mogelijk en kan losse koppelingen behouden.
- Als je een interface opnieuw gebruikt voor polymorfisme, moet je overerving en compositie combineren.
- Zo moet je overerving gebruiken om de DiscountPolicy-interface te implementeren.
Bron
- Objecten