There is a class named "Bill".
Bill can be either "Electricity" , "Food" or "Customer" which are all POJO.
So it contains three objects:
public class Bill{
private Electricity el1;
private Food el2;
private Customer el3;
//setters and getters
public setElectricity(...)
...
}
List of Bills are populated using some DTOs.
And each time, I need to check all elements to be sure what type of bill am I having.
My goal is to refactor this design.
I could also have one object and set the content regarding to the type, but is it having any standard pattern?
Is there any pattern for classes who can be a class based on the type that is requested?
I mean Bill will be either electricity, food or customer regarding to the populating time.
Note: My application favored composition over inheritance
It is also a “design by contract” based application.
Edit:
Bill is not an abstract of it's objects.
Lets assume, food is just specification of food like color and receipt!
A bill can be one and only one of the object at a point of time.
Bill is an abstract entity hence it should be an abstract class. All other type of bills should extend from it such as : ElectricityBill, FoodBill, GasBill etc
If ElectricityBill, FoodBill, GasBill has some common functionality, then create Bill as abstract class and extend other classes from bill.
If they have altogether different behaviour and state (which i doubt)then create Bill as interface and let other concrete class implement them.
i usually call it simple factory pattern(dont confuse it with factory method/abstract factory pattern)
public class BillFactory
{
Bill createBill(String type)
{
if(type.equals("Electricity"))
{
bill=new ElectricityBill();
}
........
}
}
As you have a big object with many parameters out of which some can be optional.
You can use Builder Pattern for creating the instance of your Bill class.
Unlike the abstract factory pattern and the factory method pattern
whose intention is to enable polymorphism, the intention of the
builder pattern is to find a solution to the telescoping constructor
anti-pattern. The telescoping constructor anti-pattern occurs when the
increase of object constructor parameter combination leads to an
exponential list of constructors. Instead of using numerous
constructors, the builder pattern uses another object, a builder, that
receives each initialization parameter step by step and then returns
the resulting constructed object at once.
Suppose you are building a house:
public House getHouse() {
return this.houseBuilder.getHouse();
}
public void constructHouse() {
this.houseBuilder.buildBasement();
this.houseBuilder.buildStructure();
this.houseBuilder.bulidRoof();
this.houseBuilder.buildInterior();
}
Example from Java Papers
If Bill only can contain one instace, why dont u use a interface?
public interface Billable {
double getPrize();
}
public class Electricity implements Billable {
#Override
public double getPrize() {
return 20.0;
}
}
public class Bill {
/**
* Billable to bill.
*/
Billable billable;
/*
* Discount percent applied to bill.
*/
#Min(0)
#Max(100)
double discount;
/**
* VAT percent applied to bill.
*/
#Min(0)
#Max(100)
double vat;
public Bill(#NotNull Billable billable) {
this.billable = billable;
discount = 10.0;
vat = 21.0;
}
public double getFinalPrize() {
double discountFactor = 1 - discount / 100;
double vatFactor = 1 + vat / 100;
return billable.getPrize() * discountFactor * vatFactor;
}
public static void main(String[] args) {
Electricity electricity = new Electricity();
Bill electricityBill = new Bill(electricity);
System.out.println(electricityBill.getFinalPrize());
}
}
Related
I am working on a shopping cart application which will output price of cart.
I have 3 classes for this Cart, Purchase, Product
public class Product {
private int id;
private String name;
private double price;
Offer offer;
// getter setter
public double getPrice(int quantity) {
return offer.getPrice....
}
}
public class Purchase {
Product product;
int quantity;
// getter setter
public double getPrice() {
return product.getPrice(quantity);
}
}
public class Cart {
List<Purchase> purchase = new ArrayList<Purchase>();
Offer offer;
Integer loyalityPoints;
//getter setter
public double getTotal(){
double total = 0;
for (Purchase purchase : purchase) {
total += purchase.getPrice();
}
double finalPrice = offer.getPrice(total,....;
return finalPrice;
}
}
As shown above individual product can have offer and cart can also have offer.
Initially I thought of having offer factory.
OfferPrice can be abstract class & its child could be buyonegetoneprice, buytwogetoneprice, 50precentoffprice but then input for buyonegetoneprice will be qunatity and price and input for 50precentoffprice is only price.
This means 2 different method but implementor of OfferPrice is concerned with only one implementation.
Also how could offer on cart look like? offer on cart can be based on customer loyalityPoints or 50percentoff or something else.
How to design these offers for cart and individual product in a way that could be extensible?
From your example you may need different Offer strategy. In my opinion the You should have all these three classes loosely coupled by using interfaces. Create OfferStrategy and subclasses like Product based offer, Price based offer etc.
This also looks like something that can benefit from Rules engine (You can dynamically change Offer for entire application without stopping the application)
Here is my suggestion for the design (Interfaces for each class, strategy to encapsulate different Offer algorithms which internally use Rules):
*Ixxx represents interface, <- represents is a relation
IOffer <- Offer , IProduct <- Product , IPurchase <- Purchase , IOfferStragegy <- OfferStrategy* (Different implementations with common interface method)
ICart <- Cart
Cart has products and offers.
Here are the benefits/reason for doing this :
Assuming that the Offer and Offer implementation are going to keep changing thus needs Interfaces and ability to change at run time.
Cart price is determined based on offer strategy
Let's say I have 2 classes in my model :
public class Account {
int capital;
int numero
}
public class SavingAccount extends Account{
double rate;
}
So when I have to save or retrieve an account in a database using JDBC, it works but for the binding it is OK for capital and numero but for rate I need to check the type and cast it :
if(account.getType() == AccountType.SAVINGACCOUNT) {
((SavingAccount)Account).setRate(result.getDouble("rate"));
}
Is it possible to do otherwise than that or than have 2 different methods ?
The last and just-before-implementation class is the SavingAccount. SavingAcccount contains rate's getter and setter methods. So, whenever you use getRate(), you should type cast your Account to SavingAccount, because in the heap space of SavingAccount you have getRate() method.
Because the final implementation is via SavingAccount, you also provide via TypeChecking AccountType.SAVINGACCOUNT for the correct database transactions.
When you do your executions via Account instance, it gives you polymorphic power. That's why it's important.
So, in your scenario, I don't see any other solution exists. You are doing good.
Is it possible to add multiple attributes to an Object attribute in a class? For example, I have a queue for a bar where you can order drinks by providing: drink name, drink quantity and table number. Do I have to create a variable for each or can I store multiple attributes in a single Object foo? Ty!
You will have to define a class (i.e. class DrinkOrder) and enumerate the fields of that class -- i.e. a String drinkName, int quantity, String tableIdentifier, etc.). Then when you instantiate that class into an instance, each instance can hold as many values as you have defined fields.
// Should protect the fields with accessors, implement Comparable, etc.
public class DrinkOrder {
public String drinkName;
public int quantity;
}
// Somewhere else
DrinkOrder alex = new DrinkOrder();
alex.drinkName = "Beer";
alex.quantity = 1;
DrinkOrder andy = new DrinkOrder();
andy.drinkName = "Amaro Averna";
andy.quantity = 1;
System.out.println("Andy wants " + andy.quantity + " " + andy.drinkName); // => Andy wants 1 Amaro Averna
You should take advantage of Java training (plentiful on the web) such as the original Java Tutorials or Josh Bloch's "Effective Java" or Kathy Sierra's "Head First Java"
I'm hoping someone can help explain the law of demeter to me. If I have a class which I'm assuming is an aggregate root and within that have a collection of child classes is it illegal to update the properties of those child classes by accessing them through the aggregate root?
e.g.
public class Company
{
// company has a number of employees
public List<Employee> Employees {get; set;}
}
public class Employee
{
// each employee has a lastname
public int Id {get; set;}
public string LastName {get; set;}
// other properties of employee
}
lets say I have a client that is accessing the Company class firstly would it be violating the law of demeter with something like.
Employee e = aCompany.Employees.Where(e => e.Id == 1).Single();
e.LastName = "MarriedName";
Or should this always be delegated to Company
public class Company
{
public UpdateEmployeeLastName(int employeeId, string newName)
{
Employee e = Employees.Where(e => e.Id == employeeId).Single();
e.LastName = newName;
}
}
in the client
aCompany.UpdateEmployeeLastName(1, "Marriedname");
The second one seems better but is there anything wrong with the client having to know the id of the Employee it wants to update?
This seems like it could start to get complicated where you have a number of nested aggregates.
Thanks
Your second option is what the Law of Demeter aims for.
Since the Law of Demeter basically states "only talk to what you know about".. whatever the "client" is in the first scenario doesn't actually know about employees at all. It knows about a Company.. but not about the intricacies of the Company internals.
Delegating to the Company gives you the flexibility to change how an employee is updated without having to change each specific instance of this functionality from the client. If one day you decide that only Active employees can have their names changed, then you would have to update every instance of option one to this:
Employee e = aCompany.Employees.Where(e => e.Id == 1 && e.IsActive).Single();
// ^^^^ active flag
e.LastName = "MarriedName";
Wrapping it up in Company makes this much nicer to deal with in future (regardless of attempting to follow the Law of Demeter or not).
The second one seems better but is there anything wrong with the client having to know the id of the Employee it wants to update?
Both of your examples know the ID of the Employee.. so I'm not sure what you mean by this. It is very common for consuming code to be aware of the ID when passing information through an Aggregate.
The post Visualization Mnemonics for Software Principles by Erik Dietrich provides a very effective trick to understand (and never forget anymore) what the Law of Demeter is.
An example of code violating the Law of Demeter
class Plane {
constructor(crew) {
this.crew = crew;
}
getPilotsName() {
this.crew.pilot.getName();
}
}
class Crew {
constructor(pilot) {
this.pilot = pilot;
}
}
class Pilot {
getName() {
// ...
}
}
It's bad, because it creates tight coupling between objects - they are dependent on internal structure of other objects.
Fixed code:
class Plane {
getPilotsName() {
this.crew.getPilotsName();
}
}
class Crew {
constructor(pilot) {
this.pilot = pilot;
}
getPilotsName() {
return this.pilot.getName();
}
}
i have got uml diagram from projectant and into entity i have got method getTotalPrice()
So this is my class:
public class UOrder {
#OneToMany
private List<Product> products;
....
public BigDecimal getTotalPrice(){
BigDecimal b = new BigDecimal(0.0);
for(Product p : products){
b.add(p.getPrice());
}
return b;
}
}
It is good idea to do it like that ? logical busines into entity ?
I have got only function in uml diagram not field totalPrice or something like that so i figure out that it must be like that ...
It's more like a matter of taste. For example, if you like Domain Driven Design philosophy it's a really good idea as the total price belongs to the UOrder class.
I think isn't bad, but I preferrer like (pseudo code):
public class UOrder {
...
public BigDecimal getTotalPrice() {
return PriceUtil.getTotalPrice(products);
}
}
public class PriceUtil {
public static BigDecimal getTotalPrice(List<Product> products) {
return sum-of-products;
}
... other userful and fancy price functions ...
}
because you usually need:
to calcuate VAT or
price of other class as Product or
price in other class as UOrder
and so on.
As an alternate point of view (an active record style data mapping object is just the persisted data in a handy form - a value object), here's what I think:
Given that you've said that the method is business logic, and given the well known domain that #Anton talks about - it's a bad idea. If you hadn't said it was business logic, I'd have questioned why you cared about that total in your application.
As an experiment, consider re-naming your mapped class UOrderData, treat it as a value object, and have a UOrder class that implements the business logic at application level.