Oracle PL/SQL-objekttyper: CREATE TYPE med eksempler

⚡ Smart oppsummering

Objekttyper i PL/SQL gjør objektorientert programmering mulig Oracle, slik at du kan modellere virkelige enheter med attributter og metoder. De støtter konstruktører, arv og likhetssammenligning, slik at en enkelt skjemanivåtype kan lagre og behandle strukturerte data.

  • 🧱 Objekttypekomponenter: En objekttype kombinerer attributter som lagrer data og medlemmer, eller metoder, som definerer behandlingslogikken.
  • 🏗️ Opprett objekt: Objekttyper opprettes på skjemanivå med CREATE TYPE, og metodene deres defineres i en egen CREATE TYPE BODY.
  • 🔧 Konstruktører: Hver objekttype har en implisitt konstruktør oppkalt etter typen, og du kan definere en eksplisitt konstruktør for å angi standardverdier.
  • 🧬 Arv: En IKKE-EN-FINAL-foreldertype utvides med UNDER, slik at en undertype arver alle forelderattributter og -medlemmer.
  • 🇧🇷 Likestilling: En ORDER-medlemsfunksjon sammenligner to objektforekomster og returnerer et negativt, null eller positivt tall.
  • 🤖 AI-hjelp: AI-assistenter som GitHub Copilot lager utkast til CREATE TYPE-definisjoner, konstruktører og ORDER-metoder fra en kommentar.

Oracle PL/SQL-objekttyper som viser CREATE TYPE med attributter og metoder

Hva er objekttype i PL/SQL?

Objektorientert programmering er spesielt egnet for å bygge gjenbrukbare komponenter og komplekse applikasjoner. Programmer er organisert rundt «objekter» snarere enn «handlinger»; det vil si at de er designet for å fungere med og samhandle med et helt objekt snarere enn én enkelt handling. Denne tilnærmingen lar programmereren fylle ut og manipulere detaljer på objekt-enhetsnivå.

Bildet nedenfor viser et eksempel på en objekttype der en bankkonto behandles som en objektenhet. Objektattributtene inneholder verdier – for en bankkonto er dette kontonummer, banksaldo og så videre – mens objektmetodene beskriver handlinger som å beregne renten eller generere en kontoutskrift, som hver krever at en prosess fullføres.

Bankkonto modellert som en objekttype med attributter og metoder i PL/SQL

In PL / SQL, objektorientert programmering er basert på objekttyper. En objekttype kan representere enhver virkelig enhet. Avsnittene nedenfor utforsker objekttyper, komponentene deres og hvordan du oppretter og bruker dem.

Komponenter av objekttyper

En PL/SQL-objekttype inneholder hovedsakelig to komponenter.

  1. attributter
  2. Medlemmer/metoder

attributter

Attributter er kolonnene eller feltene der data lagres. Hvert attributt er tilordnet datatypen som definerer behandlings- og lagringstypen for det attributtet. Et attributt kan være av et hvilket som helst gyldig PL/SQL datatype, eller det kan være av en annen objekttype.

Medlemmer/metoder

Medlemmer, eller metoder, er underprogrammer definert inne i objekttypen. De brukes ikke til å lagre data; i stedet definerer de behandlingen som utføres inne i objekttypen – for eksempel validering av data før objektet fylles ut. De er deklarert i objekttypespesifikasjonen og definert i objekttypeteksten. Teksten er valgfri: hvis ingen medlemmer er tilstede, har en objekttype ingen tekstdel.

Lag objekt i Oracle

En objekttype kan ikke opprettes på delprogramnivå; den kan bare opprettes på skjemanivå. Når objekttypen er definert i skjemaet, kan den brukes i delprogrammer. Objekttypen opprettes ved hjelp av «CREATE TYPE»-setningen, og typeinnholdet kan bare opprettes etter at objekttypen finnes.

Skjermbildene nedenfor viser CREATE TYPE-syntaksen for objektspesifikasjonen og CREATE TYPE BODY-syntaksen som definerer metodene.

CREATE TYPE-syntaks som definerer en objektspesifikasjon med attributter i Oracle CREATE TYPE BODY-syntaks som definerer metodene til en PL/SQL-objekttype

CREATE TYPE<object_type_name> AS OBJECT
(
<attribute_l><datatype>,
.
.
);
/
CREATE TYPE BODY<object_type_name> AS OBJECT
(
MEMBER[PROCEDURE|FUNCTION]<member_name> 
IS
<declarative section>
BEGIN
<execution part>
END;
.
.
);
/

Syntaks forklaring:

  • Syntaksen ovenfor viser opprettelsen av et OBJECT med attributter og en OBJECT BODY med metoder.
  • Metodene kan også overbelastes i objektkroppen.

Erklæringsinitialisering av objekttype

Som andre komponenter i PL/SQL, må objekttyper deklareres før de brukes i et program. Når objekttypen er opprettet, kan den brukes i et delprograms deklarative seksjon for å deklarere en variabel av den objekttypen.

Når en variabel deklareres som en objekttype, opprettes en ny instans av objekttypen under kjøretid, og denne nyopprettede instansen refereres til med variabelnavnet. På denne måten kan en enkelt objekttype lagre flere verdier under forskjellige instanser.

Skjermbildet nedenfor viser en variabel som deklareres som en objekttype inni en PL/SQL-blokk.

Deklarere en variabel av en objekttype i en deklarativ seksjon for PL/SQL-blokker

DECLARE
<variable_name> <object_type_name>;
BEGIN
.
.
END;
/

Syntaks forklaring:

  • Syntaksen ovenfor viser deklarasjonen av en variabel som en objekttype i den deklarative delen.

Når variabelen er deklarert som en objekttype i et underprogram, er den atomisk null – hele objektet i seg selv er null. Den må initialiseres med verdier før den kan brukes i programmet. Objekter initialiseres ved hjelp av konstruktører.

Konstruktører er den implisitte metoden til et objekt som kan refereres til med samme navn som objekttypen. Skjermbildet nedenfor viser initialiseringen av en objekttypeinstans.

Initialisere en objekttypeinstans til null ved hjelp av konstruktøren

DECLARE
<variable_name> <object_type_name>; 
BEGIN
<variable_name>:=<object_type_name>();
END;
/

Syntaks forklaring:

  • Syntaksen ovenfor viser initialiseringen av objekttypeforekomsten med en nullverdi.
  • Selve objektet er ikke lenger null når det er initialisert, men attributtene i objektet forblir null inntil verdier tilordnes dem.

Konstruktører

Konstruktører er den implisitte metoden til et objekt som kan refereres til med samme navn som objekttypen. Når objektet refereres til for første gang, kalles denne konstruktøren implisitt.

Du kan også initialisere objekter ved hjelp av disse konstruktørene. En konstruktør kan defineres eksplisitt ved å definere et medlem i objekttypens brødtekst med samme navn som objekttypen.

Eksempel 1: I det følgende eksemplet bruker vi objekttypemedlemmet til å sette inn poster i emp-tabellen med verdiene ('RRR', 1005, 20000, 1000) og ('PPP', 1006, 20000, 1001). Når dataene er satt inn, viser vi dem ved hjelp av objekttypemedlemmet. Vi bruker også en eksplisitt konstruktør til å fylle ut manager-ID-en med standardverdien 1001 for den andre posten.

Vi utfører det i følgende trinn.

  • Trinn 1: Opprett objekttypen og objekttypens brødtekst.
  • Trinn 2: Opprett en anonym blokk for å kalle objekttypen gjennom den implisitte konstruktøren for emp_no 1005.
  • Trinn 3: Opprett en anonym blokk for å kalle objekttypen gjennom den eksplisitte konstruktøren for emp_no 1006.

Trinn 1) Opprett objekttype og objekttypekropp.

Skjermbildet nedenfor viser objekttypespesifikasjonen emp_object som opprettes med attributter og medlemmer.

Opprette emp_object objekttypespesifikasjonen med attributter og medlemmer

CREATE TYPE emp_object AS OBJECT(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager NUMBER,
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2,
p_salary NUMBER) RETURN SELF AS RESULT),
MEMBER PROCEDURE insert_records,
MEMBER PROCEDURE display_records);
/

Skjermbildet nedenfor viser emp_object-typen som opprettes med den eksplisitte konstruktøren og medlemsprosedyrene.

Definere emp_object-typens brødtekst med en eksplisitt konstruktør og medlemsprosedyrer

CREATE OR REPLACE TYPE BODY emp_object AS
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2,
p_salary NUMBER)
RETURN SELF AS RESULT
IS
BEGIN
Dbms_output.put_line('Constructor fired..');
SELF.emp_no:=p_emp_no;
SELF.emp_name:=p_emp_name;
SELF.salary:=p_salary;
SELF.manager:=1001;
RETURN;
END;
MEMBER PROCEDURE insert_records
IS
BEGIN
INSERT INTO emp VALUES(emp_no,emp_name,salary,manager);
END;
MEMBER PROCEDURE display_records
IS
BEGIN
Dbms_output.put_line('Employee Name:'||emp_name);
Dbms_output.put_line('Employee Number:'||emp_no);
Dbms_output.put_line('Salary:'||salary);
Dbms_output.put_line('Manager:'||manager);
END;
END;
/

Code Forklaring

  • Code linje 1–9: Oppretter objekttypen 'emp_object' med 4 attributter og 3 medlemmer. Den inneholder definisjonen av en konstruktør med bare 3 parametere. (Den faktiske implisitte konstruktøren inneholder antall parametere som tilsvarer antall attributter som finnes i objekttypen.)
  • Code linje 10: Oppretter typekroppen.
  • Code linje 11–21: Definere den eksplisitte konstruktøren. Tilordne parameterverdiene til attributtene og gi attributtet 'manager' standardverdien '1001'.
  • Code linje 22–26: Definerer medlemmet 'insert_records', der attributtverdiene settes inn i 'emp'-tabellen.
  • Code linje 27–34: Definerer medlemmet 'display_records', som viser verdiene til objekttypeattributtene.

Utgang:

Type opprettet

Skriv brødtekst opprettet

Trinn 2) Oppretter en anonym blokk for å kalle den opprettede objekttypen gjennom den implisitte konstruktøren for emp_no 1005.

Skjermbildet nedenfor viser den anonyme blokken som kaller emp_object gjennom den implisitte konstruktøren.

Anonym blokk som kaller emp_object gjennom den implisitte konstruktøren for emp_no 1005

DECLARE
guru_emp_det emp_object;
BEGIN
guru_emp_det:=emp_object(1005,'RRR',20000,1000);
guru_emp_det.display_records;
guru_emp_det.insert_records;
COMMIT;
END;

Code Forklaring

  • Code linje 37–45: Setter inn postene ved hjelp av den implisitte konstruktøren. Kallet til konstruktøren inneholder det faktiske antallet attributtverdier.
  • Code linje 38: Deklarerer 'guru_emp_det' som objekttypen 'emp_object'.
  • Code linje 41: Uttrykket 'guru_emp_det.display_records' kaller medlemmet 'display_records', og attributtverdiene vises.
  • Code linje 42: Uttrykket 'guru_emp_det.insert_records' kaller medlemmet 'insert_records', og attributtverdiene settes inn i tabellen. Blokken lagrer deretter Transaksjonen.

Utgang:

Ansatt navn: RRR

Ansattnummer: 1005

Lønn: 20000

Leder: 1000

Trinn 3) Oppretter en anonym blokk for å kalle den opprettede objekttypen gjennom den eksplisitte konstruktøren for emp_no 1006.

Skjermbildet nedenfor viser den anonyme blokken som kaller emp_object gjennom den eksplisitte konstruktøren med tre argumenter.

Anonym blokk som kaller emp_object gjennom den eksplisitte konstruktøren for emp_no 1006

DECLARE
guru_emp_det emp_object;
BEGIN
guru_emp_det:=emp_object(1006,'PPP',20000);
guru_emp_det.display_records;
guru_emp_det.insert_records;
COMMIT;
END;
/

Produksjon

Employee Name:PPP 
Employee Number:1006 
Salary:20000 
Manager:1001

Code Forklaring:

  • Code linje 46–53: Sette inn posten ved hjelp av den eksplisitte konstruktøren.
  • Code linje 46: Deklarerer 'guru_emp_det' som objekttypen 'emp_object'.
  • Code linje 50: Uttrykket 'guru_emp_det.display_records' kaller medlemmet 'display_records', og attributtverdiene vises.
  • Code linje 51: Uttrykket 'guru_emp_det.insert_records' kaller medlemmet 'insert_records', og attributtverdiene settes inn i tabellen. Fordi bare tre argumenter sendes, setter den eksplisitte konstruktøren manager-ID-en til standardverdien 1001.

Arv i objekttype

Arveegenskapen gir en underobjekttype tilgang til alle attributtene og medlemmene av superobjekttypen, eller den overordnede objekttypen.

Underobjekttypen kalles den arvede objekttypen, og superobjekttypen kalles den overordnede objekttypen. Syntaksen nedenfor viser hvordan du oppretter overordnede og arvede objekttyper. Skjermbildet nedenfor viser overordnet (SUPER) syntaks merket som IKKE ENDELIG.

CREATE TYPE-syntaks for en IKKE-ENDELIG overordnet objekttype brukt i arv

CREATE TYPE <object_type_name_parent> AS OBJECT
(
<attribute_l><datatype>,
.
.
)NOT FINAL;
/

Syntaks forklaring:

  • Syntaksen ovenfor viser opprettelsen av SUPER-typen. NOT FINAL-klausulen tillater at typen arves.

Skjermbildet nedenfor viser den arvede (SUB) typesyntaksen som er opprettet med UNDER-nøkkelordet.

CREATE TYPE UNDER-syntaks for en underobjekttype som arver fra en overordnet objekttype

CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent>
(
<attribute_l><datatype>,
.
);
/

Syntaks forklaring:

  • Syntaksen ovenfor viser opprettelsen av SUB-typen. Den inneholder alle medlemmene og attributtene fra den overordnede objekttypen.

Eksempel 1: I eksemplet nedenfor bruker vi arv-egenskapen til å sette inn en post med leder-ID-en '1002' for posten ('RRR', 1007, 20000). Vi kjører programmet i følgende trinn.

  • Trinn 1: Opprett SUPER-typen.
  • Trinn 2: Opprett SUB-typen og brødteksten.
  • Trinn 3: Opprett en anonym blokk for å kalle SUB-typen.

Trinn 1) Opprett SUPER-typen eller overordnet type.

Skjermbildet nedenfor viser supertypen emp_object som opprettes med NOT FINAL-klausulen.

Opprette emp_object NOT FINAL supertypen for arveeksemplet

CREATE TYPE emp_object AS OBJECT(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager NUMBER,
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50),
p_salary NUMBER)RETURN SELF AS RESULT),
MEMBER PROCEDURE insert_records,
MEMBER PROCEDURE display_records)NOT FINAL;
/

Code Forklaring:

  • Code linje 1–9: Oppretter objekttypen 'emp_object' med 4 attributter og 3 medlemmer. Den inneholder definisjonen av en konstruktør med bare 3 parametere. Den er deklarert som 'IKKE ENDELIG', så den er en overordnet type.

Trinn 2) Opprett SUB-typen under SUPER-typen.

Skjermbildet nedenfor viser den arvede typen sub_emp_object og dens brødtekst som opprettes.

Oppretter den arvede typen sub_emp_object og dens brødtekst med insert_default_mgr

CREATE OR REPLACE TYPE sub_emp_object 
UNDER emp_object
(default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr);
/


CREATE OR REPLACE TYPE BODY sub_emp_object 
AS
MEMBER PROCEDURE insert_default_mgr 
IS
BEGIN
INSERT INTO emp
VALUES(emp_no,emp_name,salary,manager);
END;
END;
/

Code Forklaring:

  • Code linje 10–13: Oppretter 'sub_emp_object' som den arvede typen med ett ekstra attributt 'default_manager' og en medlemsprosedyredeklarasjon.
  • Code linje 14: Oppretter kroppen for den arvede objekttypen.
  • Code linje 16–21: Definerer medlemsprosedyren som setter inn poster i 'emp'-tabellen med verdiene fra SUPER-objekttypen, bortsett fra manager-verdien. For manager-verdien brukes 'default_manager' fra SUB-typen.

Trinn 3) Oppretter anonym blokk for å kalle SUB-typen.

Skjermbildet nedenfor viser den anonyme blokken som kaller SUB-typen og setter inn standard leder-ID-en.

Anonym blokk som kaller sub_emp_object-typen for å sette inn en standard leder-ID

DECLARE
guru_emp_det sub_emp_object;
BEGIN
guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002);
guru_emp_det.insert_default_mgr;
COMMIT;
END;
/

Code Forklaring:

  • Code linje 25: Deklarerer 'guru_emp_det' som typen 'sub_emp_object'.
  • Code linje 27: Initialiserer objektet med den implisitte konstruktøren. Konstruktøren har 5 parametere (4 attributter fra PARENT-typen og 1 attributt fra SUB-typen). Den siste parameteren (1002) definerer verdien for default_manager-attributtet.
  • Code linje 28: Kall på medlemmet «insert_default_mgr» for å sette inn posten med standard leder-ID-en som er sendt i konstruktøren.

Likhet mellom PL/SQL-objekter

Objektforekomster som tilhører samme objekttype kan sammenlignes for likhet. For å gjøre dette trenger objekttypen en spesiell metode kalt ORDER-metoden.

Denne ORDER-metoden skal være en funksjon som returnerer en numerisk type. Den tar to parametere som input (første parameter: ID-en til selvobjektinstansen; andre parameter: ID-en til en annen objektinstans).

ID-ene til de to objektforekomstene sammenlignes, og resultatet returneres som et tall.

  • En positiv verdi indikerer at SELF-objektforekomsten er større enn den andre forekomsten.
  • En negativ verdi indikerer at SELF-objektforekomsten er mindre enn den andre forekomsten.
  • Null indikerer at SELF-objektforekomsten er lik den andre forekomsten.
  • Hvis en av forekomstene er null, returnerer funksjonen null.

Skjermbildet nedenfor viser syntaksen for ORDER-medlemsfunksjonen som må inkluderes i typeinnholdet for likhetssjekken.

ORDER-medlemsfunksjonssyntaks brukt til å sammenligne objektforekomster for likhet

CREATE TYPE BODY<object_type_name_ 1>AS OBJECT
(
  ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1)
  RETURN INTEGER IS
  BEGIN
    IF <attribute_name>parameter <attribute_name>THEN
      RETURN -1; --any negative number will do
    ELSIF id>c.id THEN
      RETURN 1; --any positive number will do
    ELSE
      RETURN 0;
    END IF;
  END;
  .
  .
);
/

Syntaks forklaring:

  • Syntaksen ovenfor viser ORDER-funksjonen som må inkluderes i typeteksten for likhetssjekken.
  • Parameteren for denne funksjonen skal være en forekomst av samme objekttype.
  • Funksjonen kan kalles «obj_instance_1.match(obj_instance_2)», og dette uttrykket returnerer den numeriske verdien som vises, der obj_instance_1 og obj_instance_2 er forekomster av objekttypen.

Eksempel 1: I det følgende eksemplet sammenligner vi to objekter. Vi oppretter to instanser og sammenligner attributtet «salary» mellom dem. Vi gjør dette i to trinn.

  • Trinn 1: Opprett objekttypen og brødteksten.
  • Trinn 2: Opprett den anonyme blokken for å sammenligne objektforekomstene.

Trinn 1) Opprette objekttypen og -kroppen.

Skjermbildene nedenfor viser emp_object_equality-spesifikasjonen og dens brødtekst, som definerer ORDER-funksjonen som sammenligner salary-attributtet.

Opprette emp_object_equality-objekttypespesifikasjonen med en ORDER-funksjon Definere emp_object_equality-typen som sammenligner salary-attributtet

CREATE TYPE emp_object_equality AS OBJECT(
salary NUMBER,
ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER);
/
CREATE TYPE BODY emp_object_equality AS
ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER 
IS
BEGIN
IF salary<c.salary
THEN RETURN -1;
ELSIF salary>c.salary
THEN RETURN 1;
ELSE
RETURN 0;
END IF;
END;
END;
/

Code Forklaring:

  • Code linje 1–4: Oppretter objekttypen 'emp_object_equality' med 1 attributt og 1 medlem.
  • Code linje 6–16: Definerer ORDER-funksjonen som sammenligner attributtet 'salary' til SELF-instansen og parameterinstansen. Den returnerer en negativ verdi hvis SELF-lønnen er mindre, en positiv verdi hvis SELF-lønnen er større, og 0 hvis lønningene er like.

Code Utgang:

Type opprettet

Trinn 2) Opprette den anonyme blokken for å sammenligne objektforekomstene.

Skjermbildet nedenfor viser den anonyme blokken som sammenligner to emp_object_equality-forekomster etter lønn.

Anonym blokk som sammenligner to emp_object_equality-forekomster etter lønn

DECLARE
l_obj_1 emp_object_equality;
l_obj_2 emp_object_equality;
BEGIN
l_obj_1:=emp_object_equality(15000); 
l_obj_2:=emp_object_equality(17000);
IF l_obj_1.equals(l_obj_2)>0
THEN
Dbms_output.put_line('Salary of first instance is greater');
ELSIF l_obj_1.equals(l_obj_2)<0
THEN
Dbms_output.put_line('Salary of second instance is greater'); 
ELSE
Dbms_output.put_line('Salaries are equal');
END IF;
END;
/

Produksjon

Salary of second instance is greater

Code Forklaring:

  • Code linje 20: Deklarerer 'l_obj_1' av typen 'emp_object_equality'.
  • Code linje 21: Deklarerer 'l_obj_2' av typen 'emp_object_equality'.
  • Code linje 23: Initialiserer 'l_obj_1' med lønnsverdien '15000'.
  • Code linje 24: Initialiserer 'l_obj_2' med lønnsverdien '17000'.
  • Code linje 25–33: Skriver ut meldingen basert på tallet som returneres av ORDER-funksjonen.

Spørsmål og svar

En objekttype modellerer en enkelt virkelighetsnær enhet med attributter og metoder. samling — en VARRAY, nestet tabell eller assosiativ array — inneholder mange elementer av én datatype. Objekttyper beskriver struktur og oppførsel, mens samlinger lagrer flere verdier.

Begge sammenligner objektforekomster. En MAP-metode returnerer en enkelt skalarverdi som Oracle bruker til å sortere eller sammenligne objekter, mens en ORDER-metode sammenligner to instanser direkte og returnerer et negativt, null eller positivt tall. En type kan definere det ene eller det andre, ikke begge.

Ja. Du kan opprette en objekttabell der hver rad er en objektforekomst, eller bruke en objekttype som datatype for en tabellkolonne. Dette lar Oracle lagre strukturerte objekter direkte i databasen i stedet for bare i minnet.

En IKKE-INSTANTIBAR type kan ikke opprette objekter direkte; den fungerer som en abstract-base som andre typer utvider. Kombinert med IKKE ENDELIG definerer den en supertype hvis undertyper gir den konkrete implementeringen av de deklarerte metodene.

Bruk ALTER TYPE for å legge til eller fjerne attributter og metoder, legg til CASCADE for å oppdatere avhengige objekter, og bruk DROP TYPE for å fjerne typen. En type som fortsatt brukes av tabeller eller andre typer kan ikke fjernes før disse avhengige er håndtert først.

Spør dataordbokvisningene USER_TYPES og ALL_TYPES for typenavn, og USER_TYPE_ATTRS og USER_TYPE_METHODS for attributtene og metodene deres. Disse visningene lar deg revidere en eksisterende objektmodell uten å lese kildekoden.

Ja. GitHub Copilot utkast CREATE TYPE-spesifikasjoner, TYPE BODY-metoder, konstruktører og ORDER-funksjoner fra en kommentar. RevVis attributtdatatypene, konstruktørparameterne og arvsklausulene før du distribuerer den genererte typen.

AI-assistenter analyserer tabellene dine og foreslår objekttyper og attributtkartpings og arvshierarkier. Denne maskinlæringsgjennomgangen flagger overflødige attributter, manglende konstruktører og for dyp arv før objektmodellen når produksjon, noe som forbedrer vedlikeholdbarheten.

Oppsummer dette innlegget med: