Java Decorative Pattern Pizza Topping - java

i have to implement Pizza(American and Neapolitan) decoration pattern with 4 different toppings(Salami,Soudjouk,Onion,Pepper) which extends "TopingDecorator" class and out of them 3 will be added to pizza by "Add Pizza" command.However, the code does not add it to Pizza's TopingDecorator ArrayList. It should be something like below(I am trying to add Salami and Soudjouk to AmericanPan pizza(which extends PlainPizza class)):
AmericanPan a = new American();
Salami s = new Salami(a);
Soudjouk so = new Soudjouk(s);
Here is my PlainPizza class:
public class PlainPizza implements Pizza{
private int cost;
private String name;
private int orderID;
List<ToppingDecorator> topingsOfPizza;
public PlainPizza(int orderID){
this.orderID = orderID;
topingsOfPizza = new ArrayList<ToppingDecorator>();
}
public void addPizza(PlainPizza p) {
Pizza.allPizzas.add(p);
}
public List<ToppingDecorator> getTopingsOfPizza() {
return topingsOfPizza;
}
#Override
public int cost() {
// TODO Auto-generated method stub
return cost;
}
public int getOrderID() {
return orderID;
}
public String getName() {
return name;
}
#Override
public void addTopping() {
}
And here is my AmericanPan class:
public class AmericanPan extends PlainPizza{
// Class Instances
private final int cost = 5;
private String name;
// Constructor
public AmericanPan(int orderID) {
super(orderID);
this.name = "AmericanPan";
}
// Get Cost
#Override
public int cost() {
return cost;
}
// Get Name
public String getName() {
return name;
}
I am tryin to add Salami on American Pan in Salami class:
public class Salami extends ToppingDecorator{
private String name;
ToppingDecorator t;
public Salami(PlainPizza pizza) {
super(pizza);
this.name = "salami";
this.addToping();
}
#Override
public int cost() {
return super.cost() + 3;
}
#Override
public void addTopping() {
t = new Salami(pizza);
pizza.topingsOfPizza.add(t);
}
And I am trying to add it with code below in my function in main class which operates the whole process:
PlainPizza piz = new AmericanPan(orderID);
// Check The Toppings that Pizza contains
if(pizzatops.contains("soudjouk")){
soudjok = true;
}if(pizzatops.contains("salami")){
salami = true;
}if(pizzatops.contains("pepper")){
pepper = true;
}if(pizzatops.contains("onion")){
onion = true;
}
// Add Pizza according to Toppings
for(int g = 0;g<pizzatops.size();g++){
if(pizzatops.get(g).equals("salami")){
Salami s = new Salami(piz);
}else if(pizzatops.get(g).equals("pepper")){
Pepper p = new Pepper(piz);
}else if(pizzatops.get(g).equals("soudjouk")){
Soudjouk p = new Soudjouk(piz);
}
else if(pizzatops.get(g).equals("onion")){
Onion o = new Onion(piz);
}
}
Pizza.allPizzas.add(piz);
System.out.println("AmericanPan pizza added to order " + orderID);

You're going about this all wrong, with the decorator pattern you use different decorator classes to create different type of instances. In your case this means that you can't add multiple toppings to a pizza because the toppings are actually pizzas themselves, so Salami is a salami pizza and Pepper is a pepper pizza and not two toppings
If you want to add multiple toppings to one pizza then Decorator is not the right pattern.
Here is my simplified decorator implementation
interface Pizza {
int cost();
}
public class PlainPizza implements Pizza {
#Override
public int cost() {
return 10;
}
}
public abstract class ToppingDecorator implements Pizza {
private Pizza pizza;
public ToppingDecorator(PlainPizza aPizza) {
pizza = aPizza;
}
#Override
public int cost() {
return pizza.cost();
}
}
public class SalamiPizza extends ToppingDecorator {
public SalamiPizza(PlainPizza aPizza) {
super(aPizza);
}
#Override
public int cost() {
return super.cost() +3;
}
}
public static void main(String[] args) {
SalamiPizza p = new SalamiPizza(new PlainPizza());
System.out.print(p.cost());
}

I tnink, your implementation is wrong. Decorator pattern using interfaces, abstract classes.
Here
You can see, what is the right implementation with Java.

Related

Strategy design pattern Example?

Following is stretagy design pattern example take from here.
First of all we will create the interface for our strategy, in our case to pay the amount passed as argument.
public interface PaymentStrategy {
public void pay(int amount);
}
public class CreditCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
this.name=nm;
this.cardNumber=ccNum;
this.cvv=cvv;
this.dateOfExpiry=expiryDate;
}
#Override
public void pay(int amount) {
System.out.println(amount +" paid with credit/debit card");
}
}
public class PaypalStrategy implements PaymentStrategy {
private String emailId;
private String password;
public PaypalStrategy(String email, String pwd){
this.emailId=email;
this.password=pwd;
}
#Override
public void pay(int amount) {
System.out.println(amount + " paid using Paypal.");
}
}
public class Item {
private String upcCode;
private int price;
public Item(String upc, int cost){
this.upcCode=upc;
this.price=cost;
}
public String getUpcCode() {
return upcCode;
}
public int getPrice() {
return price;
}
}
public class ShoppingCart {
//List of items
List<Item> items;
public ShoppingCart(){
this.items=new ArrayList<Item>();
}
public void addItem(Item item){
this.items.add(item);
}
public void removeItem(Item item){
this.items.remove(item);
}
public int calculateTotal(){
int sum = 0;
for(Item item : items){
sum += item.getPrice();
}
return sum;
}
public void pay(PaymentStrategy paymentMethod){
int amount = calculateTotal();
paymentMethod.pay(amount);
}
}
public class ShoppingCartTest {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item item1 = new Item("1234",10);
Item item2 = new Item("5678",40);
cart.addItem(item1);
cart.addItem(item2);
//pay by paypal
cart.pay(new PaypalStrategy("myemail#example.com", "mypwd"));
//pay by credit card
cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
}
}
I want to ask what is use of strategy pattern here?Once we have created a strategy in main.We have access to Strategy class now.We can directly call pay() method from there?Why do we need interface , all which does is call a method?
1. I want to ask what is use of strategy pattern here?
The answer is the user who has the ShoppingCart (ShoppingCart cart = new ShoppingCart();)
2. We can directly call pay() method from there?
I don't know exactly you mean
3. Why do we need interface , all which does is call a method?
We need the interface PaymentStrategy because we need use Polymorphism to implement many way to pay (paypal or credit card), let's change the source a bit and you can see clearer:
public class ShoppingCart {
// other functions
public void pay(PaymentStrategy paymentMethod, int amount){
paymentMethod.pay(amount);
}
public void payWithStrategy() {
int amount = calculateTotal();
if (amount > 10000) { // because your credit card limit is 10000$ so you must use paypal
pay(new PaypalStrategy("myemail#example.com", "mypwd"), amount);
}
else { // you really like credit card so when the money lower than the card limit, you always choose it
pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"), amount);
}
}
}
public class ShoppingCartTest {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item item1 = new Item("1234",10);
Item item2 = new Item("5678",40);
cart.addItem(item1);
cart.addItem(item2);
cart.payWithStrategy();
}
}

I'm trying to understand the Building Pattern and I have trouble with the Director

I try to code a builder pattern for my better understanding. Mostly I relied on GOF and wikipedia.
So my Object is a house with required attribute area and some optional attributes (like windows, doors, rooms etc.)
I will show you the code. Now, I'm not really sure if its correct and I think I don't have a director? I don't get in which cases you need one and how it works.
This is my class house and the innerclass HouseBuilder
public class House {
//required
private final String area;
//optional
private int windows;
private int doors;
private int rooms;
//constructor with HouseBuilder
private House(HouseBuilder builder) {
this.windows = builder.windows;
this.doors = builder.doors;
this.rooms = builder.rooms;
}
public static class HouseBuilder {
//required
private String area;
//optional
private int windows;
private int doors;
private int rooms;
//constructor with required attributes
HouseBuilder(String area) {
this.area = area;
}
//optional attributes
public HouseBuilder windows(int windows) {
this.windows = windows;
return this;
}
public HouseBuilder doors (int doors) {
this.doors = doors;
return this;
}
//function for building
public Housebuild() {
return new House(this);
}
}
Now, I just got a class demo where I can build a house like that:
House house = new House.HouseBuilder("Downtown")
.doors(3).windows(2).build();
But this is not a director like in the books. Is my idea even correct? And why is that better than just using setters?
Thanks!
Your example illustrates classic builder. Director is something like an abstract builder, and in practise it is rarely used because the client class can handle that perfectly well. Example of a director in your case would be:
public class House
{
public final String area;
public windows;
public int doors;
public int rooms;
}
interface HouseBuilder
{
public HouseBuilder area();
public HouseBuilder windows();
public HouseBuilder doorsors();
public HouseBuilder rooms();
public House build();
}
public static class DowntownHouseBuilder implements HouseBuilder
{
House downtownHouse = new House();
public HouseBuilder area()
{
downtownHouse.area = "Downtown";
}
public HouseBuilder windows()
{
downtownHouse.windows = 3;
return this;
}
public HouseBuilder doors()
{
downtownHouse.doors = 2;
return this;
}
public HouseBuilder rooms()
{
downtownHouse.rooms = 2;
return this;
}
public House build()
{
return downtownHouse;
}
}
public static class VilaBuilder implements HouseBuilder
{
House vila new House();
public HouseBuilder area()
{
vila.area = "Downtown";
}
public HouseBuilder windows()
{
vila.windows = 24;
return this;
}
public HouseBuilder doors()
{
vila.doors = 5;
return this;
}
public HouseBuilder rooms()
{
downtownHouse.rooms = 10;
return this;
}
public House build()
{
return vila;
}
}
class Driector
{
private HouseBuilder houseBuilder;
public Driector(HouseBuilder houseBuilder)
{
this.houseBuilder = houseBuilder;
}
public House buildHouse()
{
return this.houseBuilder.area()
.windows()
.doors()
.rooms()
.buid();
}
}
class HouseConstruction
{
public static void main(String[] args)
{
Director director = new Director(new VilaBuilder());
House house = director.buildHouse();
System.out.println("Builder constructed: "+ house);
}
}
Hope this helps clarify what is a Director in Builder pattern.

Writing a static method for the following code

I need to write up a static method that takes an array of Vehicles and print each registration number in the array. The object in the array is either a Vehicle, a Car, or a Truck object reference. Finally, I need to print the registration number of the object on a single line on its own.
So the code is:
public class Vehicle {
private String registrationNumber;
public Vehicle(String rego) {
registrationNumber = rego;
}
public String getRegistrationNumber() {
return registrationNumber;
}
}
public class Car extends Vehicle {
int passengers;
public Car(String rego, int pass) {
super(rego);
passengers = pass;
}
public int getPassengers() {
return passengers;
}
}
public class Truck extends Vehicle {
int tons;
public Truck(String rego, int tons) {
super(rego);
this.tons = tons;
}
public int getTons() {
return tons;
}
}
I have to write up a static method for the following test and get the following, but I am having some trouble.
Test and expected Result
This is what I have done so far:
public static void printRegNum(Vehicle[] list){
for (int i = 0; i < list.length; i++){
System.out.println(list[i]);
}
}
The 1st way to play with your System.out.println(list[i]); is to override the toString() method in class Vehicle:
public class Vehicle {
private String registrationNumber;
public Vehicle(String rego) {
registrationNumber = rego;
}
public String getRegistrationNumber() {
return registrationNumber;
}
public String toString() {
return registrationNumber;
}
}
The 2nd way is change:
from:
System.out.println(list[i]);
to:
System.out.println(list[i].getRegistrationNumber());
Hope those can help.
Not getting where's the problem
i.e.
public static void main(String[] args){
Car car = new Car("MYCAR",4);
Truck t = new Truck("MYTRUCK", 16);
Vehicle[] myList = new Vehicle[] {car, t};
printRegNum(myList);
}
Also seems that you only need to print the "rego".
System.out.println(list[i].getRegistrationNumber());

Extend a generic holder class, have it accept only specific objects?

I am trying to understand and accomplish the task of trying to create a class that extends a generic class that accepts all types of classes. So far I have that working. I am trying to create a class that extends a generic holder class and have this class accept only specific objects.
Example, a class called "ComputerOrder" that will not accept an Apple or Orange object but only a ComputerPart or Peripheral object, such as Motherboard or Printer objects. Been stuck on this for 2 weeks. I can't for the life of me figure this concept out. Any help would be appreciated.
abstract class Product{
protected float price;
abstract float price();
public String toString() {
return "Price = " + String.valueOf(price) + " ";
}
}
class Apple extends Product{}
class Orange extends Product{}
class ComputerPart extends Product{
public ComputerPart(float p){
price = p;
}
public float price() {
return price;
}
}
class Motherboard extends ComputerPart{
protected String manufacturer;
public Motherboard(String mfg, float p) {
super(p);
manufacturer = mfg;
}
public String getManufacturer() {
return manufacturer;
}
}
class Peripheral extends Product{
public Peripheral(float p) {
price = p;
}
public float price() {
return price;
}
}
class Printer extends Peripheral{
protected String model;
public Printer(String model, float p) {
super(p);
this.model = model;
}
public String getModel() {
return model;
}
}
class Cheese extends Product{
public Cheese(float p) {
price = p;
}
public float price() {
return price;
}
}
class Cheddar extends Cheese{
public Cheddar(float p) {
super(p);
}
}
class GenericOrder<T>{
public ArrayList<T> storage = new ArrayList<T>();
private static int counter = 1;
public final int id;
public T obj;
public GenericOrder(){
id = counter;
counter++;
}
public void add(T item){
storage.add(item);
}
public T get(int in){
return obj;
}
public void getId(){
System.out.println(this.id);
}
public String toString(){
String ret = "";
Iterator<T> it = storage.iterator();
while (it.hasNext()) {
ret += it.next() + "\n";
}
return ret;
}
}
class ComputerOrder extends GenericOrder {
public void add(ComputerPart in){
if(in instanceof ComputerPart){
storage.add(in);
}
}
}
public class Tme2{
public static void main(String[] args){
ComputerOrder com = new ComputerOrder();
com.add(new Motherboard("bla", 3.33f))
}
}
You can do it like this:
class ComputerOrder<T extends ComputerProduct> extends GenericOrder<T> {
//...
}
Here, ComputerProduct is a class that extends Product and all your computer products like ComputerPart or Peripheral extend ComputerProduct. Similarly, you could create a class FoodProduct derived from Product, from which Apple, Orange and Cheese are derived:
class FoodOrder<T extends FoodProduct> extends GenericOrder<T> {
//...
}
The declaration <T extends ComputerProduct> is a type restriction, which ensures that all types of T are derived from ComputerPart, otherwise you will get a compiler error.
The ComputerOrder class is still generic, so you could instance an order for all computer products:
ComputerOrder order = new ComputerOrder<ComputerProduct>();
// Add peripherals, printers, motherboards...
// Apples, ... will throw compiler errors...
But you could also restrict it to peripherals only:
ComputerOrder order = new ComputerOrder<Peripheral>();
// Add peripherals, printers,...
// Apples, motherboards (ComputerProduct, but NOT Peripheral) will fail...

What inheritance for my Object class to weapon class & armor class

I'm making a little game with a hero having inventory filled with object.
public enum Objects_type
{
WEAPON,
ARMOR
}
public abstract class Objects_class
{
protected String name;
protected Objects_type type;
public Objects_class(String name, Objects_type type)
{
this.name = name;
this.type = type;
}
}
public abstract class Armor extends Objects_class{
int life = 0;
int res_fire = 0;
public Armor(String name, int largeur, int hauteur) {
super(name, Objects_type.ARMOR);
}
}
public abstract class Weapon extends Objects_class
{
protected int dmg_fire = 0;
public Weapon(String name) {
super(name, Objects_type.WEAPON);
}
}
public class StickOfJoy extends Weapon{
public StickOfJoy() {
super("Stick of Joy");
dmg_fire = 2;
}
}
public class ArmorOfPity extends Armor{
public ArmorOfPity()
{
super("Armor of Pity");
life = 30;
}
}
Then I have functions like :
Hero.getObject (Objects_class obj)
{
if (obj.getType == Objects_type.WEAPON)
....
}
I'd like to be able to consider the Objects_class obj as a Weapon but of course it's not possible (casting a mother to its child) so it makes me think my inheritance structure is bad.
What should I've done ?
David Conrad has some good points I recommend you read through that I won't repeat here but here is how I would do it.
Suppose you have a character that is roaming around in your game world picking up items, there can be many different items, some so different from each other in behavior they warrant the creation of a new subclass (like picking up boots vs picking up wings).
Once you pick up an item, you have the choice of letting the hero try and see what kind of item was picked up (instanceof, enums, whatever) or you can let the item figure out where it is supposed to go.
Here is a simplified example where the player has only two inventory slots, a weapon and an armor. Notice how easy it is to simply add a new item (like a health potion, or a superdupernewspecialweapon) to the mix without having to change anything in the player or do casting.
public abstract class Item {
private int ID;
private static int IDCounter;
private String name;
public Item(String name) {
this.name = name;
this.ID = IDCounter;
IDCounter++;
}
public int getID() {
return ID;
}
public String getName() {
return name;
}
public abstract void attachToPlayer(Player player);
}
public class Armor extends Item {
private int life;
private int res_fire;
public Armor(String name) {
super(name);
}
#Override
public void attachToPlayer(Player player) {
// Only equip if upgrade
if (player.getArmor().res_fire > this.res_fire)
player.setArmor(this);
}
}
public class Weapon extends Item {
private int dmg_fire;
public Weapon(String name) {
super(name);
}
// ...stuff
#Override
public void attachToPlayer(Player player) {
// Only equip this if upgrade? You decide the logic
if(player.getWeapon().dmg_fire>this.dmg_fire)
player.setWeapon(this);
}
}
public class SuperSpecialWeapon extends Weapon {
private float bonusHealthModifier = 1.0f;
public SuperSpecialWeapon(String name) {
super(name);
}
#Override
public void attachToPlayer(Player player) {
// This bonus adds +100%HP bonus to the player!
int hp = (int) ((1 + bonusHealthModifier) * player.getHealth());
player.setHealth(hp);
player.setWeapon(this);
}
}
public class Potion extends Item {
private int health = 100;
public Potion() {
super("HealthPotion");
}
#Override
public void attachToPlayer(Player player) {
// If the player has room for one more potion, pick this up
Potion[] potions = player.getHealthPotions();
for (int i = 0; i < potions.length; i++) {
if(potions[i]==null){
potions[i] = this;
break;
}
}
}
// ..other stuff
}
And finally the player
public class Player {
private Armor armor;
private Weapon weapon;
private String name;
private Potion[] healthPotions = new Potion[10];
private int health;
public Player(String name) {
this.name = name;
}
public Armor getArmor() {
return armor;
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public void setArmor(Armor armor) {
this.armor = armor;
}
public void setHealth(int health) {
this.health = health;
}
public int getHealth() {
return health;
}
public Potion[] getHealthPotions() {
return healthPotions;
}
}
There is no need of Objects_type, since objects in Java know what type they are, and their type can be tested with the instanceof operator. You say that you cannot cast "a mother to its child", but it is possible to downcast an object to a child type. In general, it could throw a ClassCastException, but if you have tested it first with instanceof, that won't happen.
public class Objects_class {
protected String name;
public Objects_class(String name) {
this.name = name;
}
}
public class Armor extends Objects_class {
int life = 0;
int res_fire = 0;
public Armor(String name, int largeur, int hauteur) {
super(name);
}
}
public class Weapon extends Objects_class {
protected int dmg_fire = 0;
public Weapon(String name) {
super(name);
}
}
public class Hero {
public void getObject(Objects_class obj) {
if (obj instanceof Weapon) {
Weapon weapon = (Weapon) obj;
wield(weapon);
}
if (obj instanceof Armor) {
Armor armor = (Armor) obj;
wear(armor);
}
}
}
I have removed the abstract modifier from the classes since there is no need of it, but perhaps you wanted it to ensure that those base classes are never instantiated. Also, I would change the name of Objects_class to something like Item since the words Object and class have particular meanings that could cause confusion. I would also rename Hero's getObject method to something like pickUpItem since it isn't a getter, in the Java sense.

Categories