Kiedy tworzyć zmienne publiczne a kiedy prywatne wg nowoczesnego podejścia?

0

Klasycznie uczą by prawie wszystko robić private i dodawać getterozę i setterozę.

U @jarekr000000 widziałem w kodzie, że wali publiczne jak są final. A co gdy zmienne nie są final?

przykładowo, mam taką encję:

@Entity
public abstract class Vehicle {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public Long id;

	@OneToOne
	public Driver driver;

	@OneToMany
	public Set<Order> orders = new HashSet<>();

	public int mileage;
	public LocalDate purchaseDate;

	@Transient
	private List<GpsScreenShot> gpsScreenShots = new LinkedList<>();

	public Vehicle() {
	}

	public void addGpsScreenShot(GpsScreenShot gpsScreenShot) {
		gpsScreenShots.add(gpsScreenShot);
	}

	public List<GpsScreenShot> getCopyOfGpsScreenShots() {
		return new LinkedList<>(gpsScreenShots);
	}
}

i co, może tak być ?

0

Podchodzisz do problemu ze złej strony. Jeśli zastanawiasz się co wystawić to weź pod uwagę co twoja klasa robi i co w związku z tym jest potrzebne użytkownikowi klasy. Zrób taki interfejs, by użytkownik tej klasy nie popsuł jej spójności korzystając z wystawionych mu metod i pól. Nie zawsze się to udaje (i nie zawsze to ma sens, bo np builder nie martwi się spójnością swojego stanu do momentu odpalenia metody build), ale generalnie w hermetyzacji chodzi właśnie o zachowanie spójności stanu obiektu przez odcięcie bezpośredniego dostępu do niego.

@jarekr000000 stosuje public final dla niemutowalnych obiektów będących częścią klas wartościowych. W takim przypadku to ma sens, bo taka klasa jest właśnie po to, by przechowywać kilka obiektów i tyle. Finalnych pól z niemutowalnymi obiektami nie zmienisz normalnym kodem (tzn bez refleksji) więc takie pola można wystawiać nie narażając się na popsucie spójności stanu z zewnątrz.

0
Julian_ napisał(a):

U @jarekr000000 widziałem w kodzie, że wali publiczne jak są final. A co gdy zmienne nie są final?

To chyba w jakimś legacy kodzie :-) (mam taki czasem, ale co tu dużo mówić - płaczemy i naparzamy getery). Publiczne pola niefinal to recepta na kleskę.
Gorzej: jak masz jakiś private java.util.List<Person> persons; i dorobisz do niego publicznego gettera public List<Person> getPersons() { return this.persons; } .
To masz w zasadzie pole publiczne z nieoficjalnym seterem. Jak ja lubie widzieć w kodzie kwiatki: x.getPersons().add(y);. Co gorsza, w niektórych kiepskich frameworkach (z okolic Java EE) nie da się inaczej. (np. JAXB).

Wibowit napisał(a):

Zrób taki interfejs, by użytkownik tej klasy nie popsuł jej spójności korzystając z wystawionych mu metod i pól. Nie zawsze się to udaje (i nie zawsze to ma sens, bo np builder nie martwi się spójnością swojego stanu do momentu odpalenia metody build),

Dlatego javowe mutowalne buildery to bieda.
Łatwo się naciąć robiąc coś takiego:

var contractBuilder = Conctract.newBuilder().fixed().withAddress("blotna 33");
var contract1 = contractBuilder.withAmount(1500100900).build();
var contract2 = contractBuilder.withAmount(22222).build();

Pomijając już nawet inne biedy.

2

Pisz w Kotlinie, nie będziesz miał tego problemu.
Dla mnie publiczne, niefinalne pola klasy to coś co nie powinno się znaleźć w klasie publicznej, a w prywatnej też w wyjątkowych przypadkach (w sumie sam nie wiem jakich).
To co tu wrzuciłeś to z jednej strony proszenie się o kłopoty, bo wypuszczanie na zewnątrz pól klasy to zwyczajnie kompromis pozwalający uniknąć pisania niepotrzebnego kodu kosztem ograniczenia sobie możliwości zmian tej klasy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1