Composition over Inheritance and Tight Coupling - java

I am a complete beginner so forgive my ignorance.
I have created a project where I have used composition in some classes.
In my Cinema class I have a Schedule object.
public class Cinema {
private String name; //set via constructor
private int seatCount; // set in constructor
private int rowCount; // set in constructor
private int cleanUpTime; //set via constructor
private LocalTime openTime = LocalTime.of(9, 30);
private LocalTime closeTime = LocalTime.of(23, 59);
private LocalTime peakTime = LocalTime.of(16, 30);
private int costPerHour; //set via constructor
private Schedule schedule = new Schedule(this);
//Constructors, other methods....
}
A Schedule belongs to a Cinema. It needs a Cinema object for some of its methods. A Schedule can not exist without a Cinema.
When reading about OOP I am led to believe that I have created a class that is now tightly coupled to another class and that is potentially bad.
Therefore how could I improve this design?
I have a few tightly coupled classes it seems. e.g Booking class and Customer class. A booking has a Customer and a Customer contains a list of all Bookings they have made.
I thought I was using composition and that would be good but now I am confused as I have read about coupling.
Please help me understand.

There has to be some coupling. A Cinema and a Schedule are not completely independent.
A Schedule belongs to a Cinema.
So far, so good.
It needs a Cinema object for some of its methods.
Nope. A Schedule object should be able to stand on it's own.
Since you haven't provided any code, I'll make the following assumptions.
A cinema shows one or more movies.
A movie has a schedule for each day of the week, for as long as the movie is shown.
So here's a Schedule class.
public class Schedule {
private final Calendar showingTimestamp;
public Schedule(Calendar showingTimestamp) {
this.showingTimestamp = showingTimestamp;
}
public Calendar getShowingTimestamp() {
return showingTimestamp;
}
public int getShowingWeekday() {
return showingTimestamp.get(Calendar.DAY_OF_WEEK);
}
}
The only field on the Schedule class holds a showing date and a showing time. I showed you how to use a Calendar method to get the weekday.
Here's a bare bones Movie class.
public class Movie {
private final String name;
private List<Schedule> showingList;
public Movie(String name) {
this.name = name;
this.showingList = new ArrayList<>();
}
public void addShowing(Schedule schedule) {
this.showingList.add(schedule);
}
public List<Schedule> getShowingList() {
return Collections.unmodifiableList(showingList);
}
public String getName() {
return name;
}
}
The Movie class knows about the Schedule class. The Schedule class does not know about the Movie class.
Finally, here's the Cinema class.
public class Cinema {
private final String name;
private List<Movie> currentMovieList;
public Cinema(String name) {
this.name = name;
this.currentMovieList = new ArrayList<>();
}
public void addCurrentMovie0(Movie movie) {
this.currentMovieList.add(movie);
}
public void removeMovie(Movie oldMovie) {
for (int index = currentMovieList.size() - 1; index >= 0; index--) {
Movie movie = currentMovieList.get(index);
if (movie.getName().equals(oldMovie.getName())) {
currentMovieList.remove(index);
}
}
}
public List<Movie> getCurrrentMovieList() {
return Collections.unmodifiableList(currentMovieList);
}
public String getName() {
return name;
}
}
The Cinema class knows about the Movie class, and indirectly, about the Schedule class. The Movie class does not know about the Cinema class.
I hope this has been helpful.

It is fine to have a Cinema object and list of Schedule objects inside it. One to Many relationship I suppose.

Where suitable, using composition instead of inheritance is indeed a good design practice. Your question is not really about that, though: I don't see a plausible inheritance-based alternative to the composition you have formed.
Suppose that you were trying to design classes for a system that can distinguish IMAX cinemas from other cinemas, with a consistent interface but different behavior. You might consider creating ImaxCinema as a subclass of Cinema and overriding methods as needed to customize its behavior:
class ImaxCinema extends Cinema {
#Override
int getScreenWidth() {
// ...
}
}
That's the the "inheritance" alternative.
On the other hand, you might create an interface ProjectorType, with implementations Standard and Imax that implement the varying behavior. If you give the Cinema class a member of type ProjectorType then you can provide for the varying behavior by the class of the object assigned to that member:
class Cinema {
ProjectorType projector;
int getScreenWidth() {
return projector.getScreenWidth();
}
}
That's a common form of the "composition" alternative.
Your situation does not bear on inheritance vs. composition because no customization of behavior is involved.
Avoiding tight coupling between classes is a separate consideration, and also a good design principle. Your Cinema and Schedule classes are indeed tightly coupled, as is evident already in the fact the Schedule's constructor requires a Cinema argument.
Consider, however, the iterators of Collections classes. Each one is inherently specific to a particular collection class, as it must navigate the idiosynchratic internal data structures of that class to do its job properly. Each iterator's class is therefore tightly coupled to the associated collection class, and that's OK. That avoiding tight coupling is generally a good principle does not mean that the quality of every single design is anticorrelated with the degree of coupling.
In your particular case, I don't quite see what advantage you get from the Schedule class, nor either why it needs to be tightly coupled to Cinema. Possibly, you can break the coupling, maybe by moving members of Cinema into the Schedule class, and having Cinema access them by invoking appropriate methods of Schedule. Alternatively, it might make more sense to just merge Schedule into Cinema instead of having it as a separate class. If neither of those is viable, then you could consider going all the way and making Schedule an inner class of Cinema.

Good sense, indeed tight coupling. Prevent it here by creating a new Interface, making Schedule more reusable probably. In the interface place all methods you want to use from Cinema. The IDE's compiler will help you there. Do not forget to add #Overridable in Cinema, for those interface methods.
public class Cinema implements Schedulable {
private final Schedule schedule = new Schedule(this);
public class Schedule {
public void Schedule(Schedulable schedulable) { // Instead of Cinema

Related

How to alter the design so that entities don't use injections?

I've read and came to realize myself that entities (data objects - for JPA or serialization) with injections in them is a bad idea. Here is my current design (all appropriate fields have getters and setter, and serialVersionUID which I drop for brevity).
This is the parent object which is the head of the entity composition graph. This is the object I serialize.
public class State implements Serializable {
List<AbstractCar> cars = new ArrayList<>();
List<AbstractPlane> planes = new ArrayList<>();
// other objects similar to AbstractPlane as shown below
}
AbstractPlane and its subclasses are just simple classes without injections:
public abstract class AbstractPlane implements Serializable {
long serialNumber;
}
public class PropellorPlane extends AbstractPlane {
int propellors;
}
public class EnginePlane extends AbstractPlane {
List<Engine> engines = new ArrayList<>(); // Engine is another pojo
}
// etc.
In contrast, each concrete type of car requires a manager that holds some behavior and also some specific form of data:
public abstract class AbstractCar implements Serializable {
long serialNumber;
abstract CarData getData();
abstract void operate(int condition);
abstract class CarData {
String type;
int year;
}
}
public class Car1 extends AbstractCar {
#Inject
Car1Manager manager;
Car1Data data = new Car1Data(); // (getter exists per superclass requirement)
void operate(int i) { // logic looks weird but makes the example
if (i < 0)
return manager.operate(data);
else if (i > 1)
return manager.operate(data, i);
}
class Car1Data extends CarData {
int property1;
{
type = "car1";
year = 1;
}
}
}
public class Car2 extends AbstractCar {
#Inject
Car2Manager manager;
Car2Data data = new Car2Data();
void operate(int i) {
if (i < 31)
return manager.operate(data);
}
class Car2Data extends CarData {
char property2;
{
type = "car2";
year = 12;
}
}
}
// etc.
The CarxManager are #Stateless beans which perform operations on the data (the matching CarxData) given to them. They themselves further use injections of many other beans and they are all subclasses of AbstractCarManager. There are O(100) car types and matching managers.
The issue when serializing the State is that serializing the list of abstract cars does not play well with the injections in the subclasses. I'm looking for a design that decouples the injection from the data saving process.
My previous related questions: How to serialize an injected bean? and How can I tell the CDI container to "activate" a bean?
You can use the repository pattern. Place your business logic into a service and inject the repository (which abstracts the persistence mechanism) and manager into that. The repository hides the persistence implementation details from the business service and the entities are just simple POJOs.
It would look something like the below with Foo being the id of the entity Bar:
public class CarService {
#Inject
CarRepository carRepository;
#Inject
CarManager manager;
piblic void operate(final Foo foo) {
Bar myBar = carRepository.retrieve(foo);
manager.doSomethingTo(myBar);
carRepository.persist(myBar);
}
}
See also: Repository Pattern Step by Step Explanation, http://deviq.com/repository-pattern/. Some frameworks such as Spring Data JPA or deltaspike already implement the repository pattern for you, all you need to do is provide an interface like the following and they generate the implementation in the background:
#Repository
public interface CarRepository extends EntityRepository<Car, UUID> {}
Mark in answer to your request for more detail I am going to provide a remodeled solution because the example in the question really did not make sense to me and exhibits quite a few anti-patterns which lead to problematic software.
To find a good solution to the problem touches on a lot of different considerations, many of which are very large topics with many books written about them, but I will try my best to illustrate my thinking based on these to solve the above problem.
And apologies as I have no doubt you are aware of many of these, but I shall assume limited knowledge for the sake of clarity.
The first step in solving this problem is not about code, but about the model itself, model driven development is covered extensively in Eric Evan's book as mentioned in the comments below. The model should drive the implementation and should also exist on its own tier as part of a layered architecture and is made up of entities, value objects and factories.
Model Driven Development
In the model given in the question we have something called a State, which contains AbstractPlanes and AbstractCars. You are using JPA to persists the State which is effectively an aggregate of your planes and cars. Firstly calling anything a State in software is a bad smell because pretty much everything has some sort of state, but calling what we have here which is an aggregate the State makes even less sense.
How does one State differ from another? Is one car part of one State and another part of a different State or is it the case that all planes and cars belong to a single instance of State. What is the relationship between planes and cars in this scenario? How does a list of planes and a list of cars have any relation to a single State entity?
Well if State was actually an Airport and we were interested in how many planes and cars were currently on the ground, then this could be the correct model. If State was an Airport it would have a name or identity such as its airport code, but it does not and so...
... in this case, it seems that State is an object which is being used as a convenience to allow us to access the object model. So we are effectively driving our model by implementation considerations, when we should doing it the other way round and driving our implementation from our model.
Terms like CarData are also problematic for the same reason, creating a Car entity and then a separate object to store its Data is messy and confusing.
Failure to get the model right results in software that is at best confused and at worst completely non-functional. This is one of the largest causes of failed IT programmes and the bigger the project the harder this stuff is to get right.
Revised Model
So from the model I understand that we have Cars and we have Planes, instances of which are all unique entities with their own identity. They seem to me to be separate things and so there is no point in persisting them wrapped in some aggregate entity.
public class Plane {...}
public class Car {...}
Another consideration is the use of abstract classes in the model, generally we want to apply the principle of favoring composition over inheritance because inheritance can result in hidden behaviors and it can make a model hard to read. For example why have we got a ProperllerPlane and an EnginePlane? Surely a propeller is just a type of engine? I have greatly simplified the model:
public class Plane implements Serializable {
#Id
private String name;
private String model;
private List<Engine> engines;
The Plane is an entity with its own attributes and identity. There is no need to have additional classes which represent nothing in the real world just to store attributes. The engine object is currently an enum representing the type of engine used in the plane:
public enum Engine {
PROPELLER, JET
}
If the engine itself were to require an identity, as in real life engine serial numbers and things are tracked, then we would change this to an object. But we might not want to allow access to it except through a Plane entity instance, in which case the Plane will be known as a aggregate root - this is an advanced topic and I would recommend Evan's book for more details on aggregates.
The same goes for the Car entity.
#Entity
public class Car implements Serializable{
#Id
private String registration;
private String type;
private int year;
The above is all you need from what was provided in the question for the basis of your model. I have then created a couple of factory classes which handle creation of instances of these entities:
public class CarFactory {
public Car makePosrche(final String registrationNumber) {
Car porsche = new Car();
porsche.setRegistration(registrationNumber);
porsche.setType("Posrshe");
porsche.setYear(1986);
return porsche;
}
}
public class PlaneFactory {
public Plane makeSevenFourSeven(final String name) {
Plane sevenFourSeven = new Plane();
List<Engine> engines = new ArrayList<Engine>();
engines.add(JET);
engines.add(JET);
engines.add(JET);
engines.add(JET);
sevenFourSeven.setEngines(engines);
sevenFourSeven.setName(name);
return sevenFourSeven;
}
public Plane makeSpitFire(final String name) {
Plane spitFire = new Plane();
List<Engine> engines = new ArrayList<Engine>();
engines.add(PROPELLER);
spitFire.setEngines(engines);
spitFire.setModel("Spitfire");
spitFire.setName(name);
return spitFire;
}
}
What we are also doing here is separating out concerns as according to the Single Responsibility Principle each class should only really do one thing.
Now that we have a model we need to know how to interact with it. In this case we would most likely if using JPA persist the Cars in a table called Car and the Planes likewise. We would provide access to these persisted entities via repositories, CarRepository and PlaneRespository.
You can then create classes called services which inject the repositories (and anything else you require) to perform CRUD (Create Read Update Delete) operations on the instances of cars and planes and also this is the point where you can apply your business logic to these. Such as your method:
void operate(int i) {..}
By structuring your code this way you decouple the model (entities and value objects) from how they are persisted (repositories) from the services which operate on them as mentioned in your question:
I'm looking for a design that decouples the injection from the data saving process.
A possibility is to remove the property, so it won't be picked up by the serializers. This can be achieved be getting it programmatically.
private Car2Manager getCar2Manager() {
CDI.current().select(Car2Manager.class).get();
}
I would not consider this a clean solution, but it should be a workable "solution"
Also which might work is using JPA's #Transient:
#Inject
#Transient
Car2Manager manager;
I have not tested this, so it might not work.
What is the entry point?
Is this a web application, a rest service, a soap service, or event a scheduler?
Injection frameworks almost always separate data and service. Data are always POJO, containing absolutely no business logic. Here, assuming this is a rest-service, i will do the following:
public class SSOApplication {
public class State implements Serializable {
List<AbstractCar> cars = new ArrayList<>();
List<AbstractPlane> planes = new ArrayList<>();
// other objects similar to AbstractPlane as shown below
}
public abstract class AbstractPlane implements Serializable {
long serialNumber;
}
public class PropellorPlane extends AbstractPlane {
int propellors;
}
public class EnginePlane extends AbstractPlane {
List<Engine> engines = new ArrayList<>(); // Engine is another pojo
}
public abstract class AbstractCar implements Serializable {
long serialNumber;
abstract CarData getData();
}
public static class CarData {
String type;
int year;
}
public class Car2Data extends CarData {
char property2;
{
type = "car2";
year = 12;
}
}
public static class Car1Data extends CarData {
int property1;
{
type = "car1";
year = 1;
}
}
public static class Car1 extends AbstractCar {
#Override
CarData getData() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
public static class Car2 extends AbstractCar {
#Override
CarData getData() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
public static interface CarManager<T extends CarData> {
void operate(T car, int index);
default boolean canHandle(T carData) {
final TypeToken<T> token = new TypeToken<T>(getClass()) {
};
return token.getType() == carData.getClass();
}
}
#ApplicationScoped
public static class Car1Manager implements CarManager<Car1Data> {
public void operate(Car1Data car, int index) {
}
}
#ApplicationScoped
public static class Car2Manager implements CarManager<Car2Data> {
public void operate(Car2Data car, int index) {
}
}
#ApplicationScoped
public static class CarService {
#Any
#Inject
private Instance<CarManager<?>> carManagers;
public void operate(int index, AbstractCar car) {
final CarData carData = car.getData();
final CarManager<?> carManager = carManagers.stream()
.filter((mng) -> mng.canHandle(carData))
.findFirst()
.orElse(IllegalArgumentException::new);
carManager.operate(carData, index);
}
}
}
If you could alter your flow than perhaps you could do something like this:
class Car1InnerService {
#Inject
Car1Manager manager;
void operate(int i, Car1 car) {
if (i < 0)
return manager.operate(car.getData());
else if (i > 1)
return manager.operate(car.getData(), i);
}
}
}
I introduced some inner service which will operate on Car1 and use Car1Manager for it. Your AbstractCar class will also of course lose it's operate method because from now on your service will handle it. So now instead of calling car1.operate(i) you will have to make a call via Service like this:
public class SampleCar1ServiceUsage{
#Inject
Car1InnerService car1InnerService;
public void carManipulator(List<Car1> carlist){
int i = 0; //I don't know why you need this param therefore i just increment it
for(Car1 car: carlist){
car1InnerService.operate(i, car);
i++;
}
}
}
Of course you should introduce similar functionality for every other AbsractCar children (perhaps even extract some abstraction if necessary like for example AbsractCarInnerService which would define operate method or some interface which would do the same if you don't want any other solid methods in it). However this answer is still somehow related to #Justin Cooke answer and in my opinion you should definitely check those patterns which he mentioned in his post.

Java - Is this a correct way of writing a single super-class with multiple sub-classes which implements a single interface?

I'm trying grasp the concept of interfaces by an example simple as possible that came through my mind after already having these classes. So I began sub-classing each other after reading a bit about inheritance and interfaces, then decided that Person should be my super-class in this case. I think this is completely wrong but I am not sure how much wrong is in it?
The interface:
public interface BasicAgenda
{
//Person super-class
public String getName();
public String getPhoneNumber();
public void setName(String name);
public void setPhoneNumber(String phoneNumber);
//Event sub-class of Person
public String getBirthDay();
public String getMeeting();
public String getDebate();
public void setBirthDay(String birthDay);
public void setMeeting(String meeting);
public void setDebate(String debate);
//Time sub-class of Event
public int getSecond();
public int getMinute();
public int getHour();
public void setSecond(int second);
public void setMinute(int minute);
public void setHour(int hour);
public void setTime(int second, int minute, int hour);
public void nextSecond();
//MyDate sub-class of Time
public int getYear();
public int getMonth();
public int getDay();
public void setYear(int year);
public void setMonth(int month);
public void setDay(int day);
public void setDate(int day, int year, int month);
}
Classes:
public class Person
{
//some code here and there
}
public class Event extends Person
{
//some code here and there
}
public class Time extends Event
{
/some code here and there
}
public class MyDate extends Time implements BasicAgenda
{
//some code here and there
}
Thank you.
Most definitely wrong. I see far too much repetition and lack of encapsulation here. This is not a good use of inheritance.
Why do you need a custom date and time class? Wrong from beginning to end.
An Event is not a Person.
You are confusing inheritance and composition.
You are using String in a number of spots that suggest a custom class for better encapsulation.
I don't know your requirements, but here's an alternative idea:
public class Person {
private String firstName;
private String lastName;
private LocalDate birthdate;
private List<Event> events;
// You add the rest
}
public class Event {
private String description;
private LocalDateTime start;
// You add the rest
}
You have Meeting and Debate in your question. Maybe your Event needs an enumeration of types.
No need for any inheritance. It's all HAS-A: composition.
When a class A extends a class B then it means the developer intentds that object of class B behaves like A. You typically extend a class when you see there is a common base class which can hold common code and then the sub classes can extend the behavior of parent base class by adding more methods. Also some times a sub class can override some behavior of its parent class. This way sub classes need not re write that common part. [Tip : do not use inheritance just to prevent code duplicacy, instead see if there is a relation of behaves like, some text says is a relationship].
You declare the interface as a contract declaration to other developers that your class will certainly provide implementation for the declared contract. It also keeps your code less coupled to the concrete logic and you can freely modify the concrete logic without affecting the dependent code. Your other classes depend just on the declared interface.
Ideally in Object oriented language code looks like a Lego block game. A class exposes its interface for which it provides the implementation, while other classes consume this interface (as composition). Both the implementing class and the dependent classes are dependent upon pure abstraction rather than concrete classes.
Above were few important tips which you can dive deep and learn. Other important keywords for you : Encapsulation. It protects your state. Hide state of your class. It shall protect you and others from direct access of your state. In future you can add rules and logoc which shall enable you to put easy checks and do logical pre or/and post processing once there is an attempt to modify the state.
Dupicate code is a sin, Avoid it try seeing if you can use composition and reuse what is already written, may be you can wrap what is already written with some additional logoc. You can extend what is already written. Choose option after giving thought.
Most important : write code. Do mistakes, read, correct your mistakes. Learn refactoring, its hard to master it but for sure you will enjoy it. All the best and happy learning.

Design for a shop - multiple product classes

I was reading about Spring and encountered an example consisting of an abstract product class with name and price fields.
Next, there is a Battery class which extends the Product class and adds a rechargable field. Then, a CDDrive class (also) extending Product but adding a capacity field.
In the real world when we often have products having many disparate attributes, how does one model arbitrary products with arbitrary properties and fields?
Does having a class for each product make sense?
So, can you guys please suggest a pattern for achieving this?
Thanks,
Ouney
Good question. We had a similar situation before where we had GUI components that shared many of their abstract parent, but each page had its own set of labels that weren't shared by others. The standoff was on. We found it silly to just keep creating subclasses because of the mutually disjoint properties they had. What did it for us was maps. First, to have a subclass is to have one or more distinguishing properties that are fist class objects. Rechargeable for batteries and capacity for cd drives in your case. Then for the properties one can't think of at the time of building, or simply differ in minor naming conventions, use maps. I demonstrate with the example below.
The product:
public abstract class Product {
String name;
Double price;
Map<String, Object> propMap;
public Product(String name, Double price) {
this.name = name;
this.price = price;
propMap = new HashMap<>();
}
public void add2propMap(String key, Object value) {
propMap.put(key, value);
}
public String toString() {
return "Product [name=" + name + ", price=" + price + ", propMap=" + propMap + "]";
}
}
The CdDrive:
public class CdDrive extends Product {
String capacity;
public CdDrive(String name, Double price, String capacity) {
super(name, price);
this.capacity = capacity;
}
}
The Battery:
public class Battery extends Product {
Boolean rechargable;
public Battery(String name, Double price, Boolean rechargable) {
super(name, price);
this.rechargable = rechargable;
}
}
Then a client:
public class Client {
public static void main(String[] args) {
List<Product> productList = new ArrayList<>();
Battery energizer = new Battery("Energizer", 12d, true);
energizer.add2propMap("numInPackage", new Integer(8));
energizer.add2propMap("make", "US");
productList.add(energizer);
CdDrive superDrive = new CdDrive("Apple Drive", 200d, "200 GB");
superDrive.add2propMap("type", "External");
superDrive.add2propMap("expandable", false);
productList.add(superDrive);
productList.forEach(p -> System.out.println(p));
}
}
Which gives this when run:
Product [name=Energizer, price=12.0, propMap={numInPackage=8, make=US}]
Product [name=Apple Drive, price=200.0, propMap={expandable=false, type=External}]
This setup made the architecture scalable, maintainable and modifiable. The map keys always reported what was in there in case in doubt. Adding is easy and so is modifying.
Does having a class for each product make sense?
In real life situation, it rarely makes sense. They are just making up some example to make you get the feeling of it.
Just imagine your online shop sells CD players, now you want to add some MD players in your product list, and you need to change your code and redeploy the application just because of it. Non-sense huh?
Unless you have bunch of specific function for some specific type of product, having a dedicated class for such type of product will make sense. (e.g. Product, PhysicallyDeliverableProduct something like that. Still there are better way to design it though)
In real life, the way to solve the issue in your question, is mostly by designing your Product to keep some arbitrary properties (e.g. keeping a Map<String,Object>, so you can put ["rechargeable", true] for a battery you add on your site.
Design pattern? I think what you are looking for is still far from required to make use of patterns. Personally I will suggest you to take a look on the book "Analysis Pattern" by Martin Fowler. You may not be able to use the design in it directly, but it give you feel on what real life design looks like
Does having a class for each product make sense?
To me it absolutely makes sense to have separate classes for separate products.
That makes your code more loosely coupled. In future if you want to change the implementation of a particular product, changing the code won't mess up the implementation of other products if you have a separate class for that. The generic methods & properties you can put in an abstract class.
a pattern for achieving this?
You might want to look at the Factory & template pattern.
You can create an interface Product & all the classes will implement that interface & define their own implementations.
Use abstract class only when you want to provide a default behaviour to your methods. For an instance have a look at the template pattern here.
An abstract class game is created which defines the play method. initialize & startPlay etc can have their respective definition in the subclasses but the play method will always run the other methods.
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
//template method
public final void play(){
//initialize the game
initialize();
//start game
startPlay();
//end game
endPlay();
}
}
If you don't intend to provide any default behaviour rather just declare the properties & methods in an interface Product & let the classes implement that.
interface Product{
String NAME="defaultName";
Integer PRICE=5;
initialCost(); // example of a generic method
}
//Note that name & price if you declare those in interface will be treated as constants.
class Battery implements Product{
Boolean rechargable =false;
public void initialCost(){
//method definition
}
}
class CdDrive implements Product{
Integer capacity = xxxx;
public void initialCost(){
//CdDrive method definition
}
}
You can create the objects as
Product product = new Battery();
Product nextProduct = new CdDrive();
this makes your code loosely coupled. Also known as programming to an interface.

Design Patterns - One public class utilizing many hidden classes

I have gone through http://www.dofactory.com/net/design-patterns in trying to find out the most efficient to create a design pattern in which "one visible class utilizes many hidden classes" to create a fluent API. Below is the code I currently have:
public class VisibleClass {
Private OrderClass order;
private ReceiptClass receipt;
public VisibleClass makeOrder() {
if (!(order instanceof OrderClass))
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (!(receipt instanceof ReceiptClass))
receipt = new ReceiptClass();
receipt.print();
return this;
}
}
class OrderClass implements IOrder {
public void make() {}
}
class ReceiptClass implements IReceipt {
public void print() {}
}
interface IOrder { void make(); }
interface IReceipt { void print(); }
Here is how I am currently using the API:
public static void main(String[] args) {
VisibleClass x = new VisibleClass();
x.makeOrder().printReceipt();
}
It this a good approach? Can a better approach be used for it?
*EDIT: Also, I should add that the VisibleClass will implement all methods of the hidden classes.
Your approach is quite good. Here some recommendations:
1 Change class member types to their interfaces as for 'Program to an interface, not an implementation' principle:
public class VisibleClass {
private IOrder order;
private IReceipt receipt;
2 Do you really need to check class types in makeOrder and printReceipt methods ? Creating instances after null check seems enough:
public VisibleClass makeOrder() {
if (null == order)
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (null == receipt)
receipt = new ReceiptClass();
receipt.print();
return this;
}
3 This approach is valid until methods of VisibleClass will be called by a single thread. If you're going to place it in a multi-thread program, you should ensure that there are only one instances of OrderClass and ReceiptClass each. There are 3 ways you can follow:
a. Create instaces of OrderClass and ReceiptClass in constructor and make VisibleClass singleton.
b. Make OrderClass and ReceiptClass singleton and remove new lines.
c. Create instances surrounded with synchronized block in makeOrder and printReceipt methods.
one visible class utilizes many hidden classes
don't do that with business classes. Fluent syntax's is great for configuration etc, but not for plain business code.
The reason is that the class itself losses control over it's state which can put it in an inconsistent state (i.e generate faulty results).
There is even a principle called Law of Demeter which is about just that.
If you have a business requirement that a receipt should be printed on a new order you should just return it as a return value.
var receipt = visibleClass.makeOrder();
As for using interfaces for entity/business classes, why do you do that? why would you want to abstract away those? The usually do not have any other dependencies or different types of implementations.
You can try using the Facade Design pattern
Or may be try using a Decorator Pattern

Call a child class method from a parent class object

I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}

Categories

Resources