HD Pg 324, Sec. 11.6.0 - exercises

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

Two questions:

Question One:
System.out.println(r.getChannel()); //should print 0
Shouldn't the pointer in the above line from exercise 2 change to

System.out.println(t.getChannel()); //should print 0

If not, please drop a hint or two, as for what is this exercise is aiming to accomplish.

Question Two:

Lets assume that the above pointer issue was just a typo. If so, which one of these two solutions would be a good code for exercise 2, overloaded methods or use of instanceof and casting to create a single method?

Code: Select all

static void reset (Object input){
        if (input instanceof TV)
          ((TV)input).setChannel(0);
        else
          ((Radio)input).setFrequency(0.0); 
}
or

Code: Select all

static void reset (TV input){    
        input.setChannel(0);
    }
    
static void reset (Radio input) {
        input.setFrequency(0.0);
}
Here are Radio & TV classes for reference

Code: Select all

class Radio{
    private double frequency = 1.1; //insert appropriate getter and setter
    
    public void setFrequency (double f){
        this.frequency = f;
    }
    
    public double getFrequency(){
        return frequency;
    }
}    

class TV{
    private int channel = 5; //insert appropriate getter and setter
    
    public void setChannel(int c){
        this.channel = c;
    }
    
    public int getChannel(){
        return channel;
    }
}
Here is the TestClass' main() for reference

Code: Select all

public static void main(String[] args){
       
       /* This segment is for Exercise 1 and not relevant to this set of questions 
        Document d = new PdfDocument();
        d.setType("pdf");
        System.out.println(d.getType()); //should print "pdf"
        */
        
        TV t = new TV();
        Radio r = new Radio();
        reset(t);
        reset(r);
        System.out.println(r.getFrequency()); //should print 0.0
        System.out.println(t.getChannel()); //should print 0
    }
Thanks

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

1. Yes, it should be t.getChannel.

2. Either one of the approaches is fine. I would use the instanceof approach because it would be easier to change later. But one could go for overloaded methods also because they look cleaner.
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

3. You are expected to reset several electronic devices in future. Refactor the code given above
such that TestClass's reset method is able to reset any new device without requiring any
change in the method code.
Incorporating the requirements of exercise 3, would you agree that it would be better coding to have overloaded reset method and introduce the following code?

Code: Select all

static void device (Object input){

        if (input instanceof TV)
          reset((TV)input);
        else
          reset((Radio)input); 
}
and of course changing TestClass' main() to call device(r) and device(t) rather than reset(r) and reset(t)?

Thanks

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

No, your device method doesn't satify the requirement.
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

Would introduction of the Electronics class and changes the TestClass' main() provide sufficient refactoring for exercise 3's requirements? If still not enough, or cleaner way of doing it - I appreciate a hint or 2. Thanks

Code: Select all

class Electronics{
    
    static void device (String input){

        TestClass tc = new TestClass();
        
        if (input.equals("TV")){
            TV tv = new TV();
            tc.reset(tv);
            System.out.println(tv.getChannel());
        
        }else if (input.equals("Radio")){
            Radio rd = new Radio();
            tc.reset(rd); 
            System.out.println(rd.getFrequency());
        }  
    }
    
}

Code: Select all

class TestClass{
    
    /* This approach works just as well in exercise 2.
    
    static void reset (Object input){
        if (input instanceof TV)
          ((TV)input).setChannel(0);
        else
          ((Radio)input).setFrequency(0.0); 
    }
    */
    
    void reset (TV input){    
        input.setChannel(0);
    }
    
    void reset (Radio input) {
        input.setFrequency(0.0);
    }
    
    public static void main(String[] args) throws IOException {
        
        /* This segment is for Exercise 1 and not relevant to this set of questions
        Document d = new PdfDocument();
        d.setType("pdf");
        System.out.println(d.getType()+"\n"); //should print "pdf"
        */
        
        //TV t = new TV(); //used in exercise 2
        //Radio r = new Radio(); //used in exercise 2
        //reset(t); used in exercise 2
        //reset(r); used in exercise 2
        
        Electronics.device("TV"); // used in exercise 3
        Electronics.device("Radio"); // used in exercise 3
        
        //used in excercise 2
        //System.out.println(r.getFrequency()); //should print 0.0
        //System.out.println(t.getChannel()+"\n"); //should print 0
        }
}


admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

You are missing the point. You have to use polymorphism/overrides. Create a common base class for TV and Radio and put an abstract reset method there. From main, just invoke reset on that common base class reference.
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

Part 1. Oh ok I get it, move on from overloading to overriding methods.

Part 2.
From main, just invoke reset on that common base class reference.
I'm missing something here. The common base class will be an abstract class in order to support the abstract reset method. What do you mean by invoke reset on that common base class reference?

However, I've made the following modifications to the code implementing method overrides. If removing the parameters violates the exercise requirements, then I am counting on further clarification of part 2 of your comments to point me to the right direction.

Code: Select all

class TestClass{
  
    public static void main(String[] args) 
        
        //Excercise 3
        TV t = new TV();
        Radio r = new Radio();
        r.reset(); 
        t.reset();
        
        //used in excercise 2 & 3
        System.out.println(r.getFrequency()); //should print 0.0
        System.out.println(t.getChannel()+"\n"); //should print 0
      }
}

abstract class Electronics{
    
    abstract void reset();
    
}

class Radio extends Electronics{
    private double frequency = 1.1; //insert appropriate getter and setter
    
    public void setFrequency (double f){
        this.frequency = f;
    }
    
    public double getFrequency(){
        return frequency;
    }
    
    @Override
    public void reset () {    
        setFrequency(0.0);
    }
}    

class TV extends Electronics{
    private int channel = 5; //insert appropriate getter and setter
    
    public void setChannel(int c){
        this.channel = c;
    }
    
    public int getChannel(){
        return channel;
    }
    
    @Override
    void reset (){
        setChannel(0);
    }
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

In TestClass:
static void reset(Electronics e){
e.reset();
}

You can pass any new device to this method.
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

Wow, is like finding the missing link to abstract classes :o

I tested it on an interface below, it works just as well.

Thanks a bunch :thumbup:

Code: Select all

interface Vehicle {
    
    void run ();
}

class Car implements Vehicle{
    private double speed;
    
    public void setSpeed (double f){
        this.speed = f;
    }
    
    public double getSpeed(){
        return speed;
    }
    
    @Override
    public void run () {    
        setSpeed(40.0);
    }
}


public class Test {
    
    static void run( Vehicle v){
       v.run();
    }


    public static void main(String[] args) {
        

        Car c = new Car();
        
        run(c); 
        
        System.out.println(c.getSpeed()); 

        
    }
    
}
Also the following are solutions to exercises 3-7. I appreciate a look see to make sure they satisfy the requirements, and any possible suggestions you might have to streamline any of them. Thanks

Code: Select all

package ocaex11;
import java.io.*;


class TestClass{
    
    static void reset(Electronics e){
       e.reset();
    }
    
    static void printCalories(Nutritionist n){
        n.printCalories();
    }
    
    public static void main(String[] args){       
        
        //Excercise 2 & 3
        TV t = new TV();
        Radio r = new Radio();
        
        //used in exercise 2 & 3
        reset(t);
        reset(r); 
        
        //used in excercise 2 & 3
        System.out.println(r.getFrequency()); //should print 0.0
        System.out.println(t.getChannel()); //should print 0
        
        System.out.println();
        
        //Excercise 4 & 5
        PumpkinPie pp = new PumpkinPie();
        pp.makePie(); //used in 4
        printCalories(pp); //used in 5
        
        ApplePie ap = new ApplePie();
        ap.makePie(); //used in 4
        printCalories(ap); // used in 5     
    }
}


abstract class Electronics{
    
    abstract void reset();
    
}

class Radio extends Electronics{
    private double frequency = 1.1; //insert appropriate getter and setter
    
    public void setFrequency (double f){
        this.frequency = f;
    }
    
    public double getFrequency(){
        return frequency;
    }
    
    @Override
    public void reset () {    
        setFrequency(0.0);
    }
}    

class TV extends Electronics{
    private int channel = 5; //insert appropriate getter and setter
    
    public void setChannel(int c){
        this.channel = c;
    }
    
    public int getChannel(){
        return channel;
    }
    
    @Override
    void reset (){
        setChannel(0);
    }
}

abstract class Nutritionist {
    
    abstract void printCalories ();            
}

class Pie extends Nutritionist {
    
    public void makePie(){
        System.out.println("Making pie.");
    }
    
    public static int getCalories(){
        return 100;
    }
    
    @Override
    void printCalories () {
        System.out.println("Average pie calories: "+getCalories()+"\n");
    }
}

class PumpkinPie extends Pie {
    
    PumpkinPie (){
        super.makePie();
    }
    
    @Override
    public void makePie(){
        System.out.println("Making pumpkin pie.");
    } 
    
    public static int getCalories(){
        return 200;
    }
    
    @Override
    void printCalories () {
        System.out.println("Pumkin pie calories: "+getCalories()+"\n");
    }
}

class ApplePie extends Pie {
    
    ApplePie(){
        super.makePie();
    }
    
    @Override
    public void makePie(){
        System.out.println("Making apple pie.");
    }
    
    public static int getCalories(){
        return 300;
    }
    
    @Override
    void printCalories () {
        System.out.println("Apple pie calories: "+getCalories()+"\n");
    }
}

//Exercise 6 & 7

abstract class Transformer {
    abstract String transform (String Data) throws IOException;
}

class XMLTransformer extends Transformer {
    
    @Override
    public String transform(String Data){
        return "xmldata.";
    }
}

class NetworkTransformer extends Transformer {
    
    @Override
    public String transform (String Data) throws IOException {
        return "data from network.";
    }
}

class TransformerFactory {
    
    static public String getTransformer(Transformer t) throws IOException{
        return t.transform("transfer method?");
    }
    
    public static void main (String[] ...args) throws IOException{
        
        XMLTransformer  xt = new XMLTransformer();
        System.out.println(getTransformer(xt));
        
        NetworkTransformer nt = new NetworkTransformer();
        System.out.println(getTransformer(nt));
        
        
    }
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

>>Wow, is like finding the missing link to abstract classes :o

Will try to improve the chapter text to make this point clearer.


If your class name is TransformerFactory and its method name is getTransformer, why it that method not returning a Transformer?
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

I hope you don't make it too obvious though. I learned more pin pointing this missing link than if it were just a section in the book :)

I was wondering that return t.transform("transfer method?"); somehow was wasting the parameter, but wasn't sure. I'll look at it more carefully!
Last edited by OCAJO1 on Mon Apr 15, 2019 1:53 pm, edited 1 time in total.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

I think this solution is a lot cleaner than the last one.

Question: Unless my code is still not addressing the exercise requirements (not sure what else can I do to it?)- since it is returning a hardcoded string, what is the point of transform method having a String parameter?

Code: Select all

//Exercise 6 & 7

abstract class Transformer {
    abstract String transform (String Data) throws IOException;
}

class XMLTransformer extends Transformer {
    
    @Override
    public String transform(String Data){
        return "xmldata.";
    }
}

class NetworkTransformer extends Transformer {
    
    @Override
    public String transform (String Data) throws IOException {
        return "data from network.";
    }
}

class TransformerFactory {
    
    private Transformer t;

    public void setTransformer(Transformer st){
        this.t = st;
    }
    
    public String getTransformer() throws IOException{
        return t.transform("");
    }
       
    
    public static void main (String[] ...args) throws IOException{
        
        TransformerFactory tf = new TransformerFactory();
        
        XMLTransformer  xt = new XMLTransformer();
        tf.setTransformer(xt);
        System.out.println(tf.getTransformer());
        
        NetworkTransformer nt = new NetworkTransformer();
        tf.setTransformer(nt);    
        System.out.println(tf.getTransformer());
        
        
    }
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

Yes, this looks better.

TransformerFactory should not have setTransformer. It is a factory, so it should create its own Transformer and return that transformer through getTransformer.
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

By making the transformers, I gather you mean to use the two transformer classes extending abstract class Transformer to make the transformers. If so, I believe the code below does this.

However, since the code still not making use of transform method's String parameter, I have to wonder if the approach is what the exercise is looking for?

If the above question is even relevant - If the return from the overridden transform methods were not hardcoded string, some code like this code segment in getTransformer method could make use of the transform method's String parameter.

Code: Select all

        private String data;
        ....
        
        if (t instanceof XMLTransformer)
            data = "xmldata";
        else if (t instanceof NetworkTransformer)
            data = "data from network";
        
        return t.transform(data);

Code: Select all

class TransformerFactory {
    
    private Transformer t;
    
    public String getTransformer(Transformer x) throws IOException{
        
        this.t = x;
        return t.transform("");
    }
       
    
    public static void main (String[] ...args) throws IOException{
        
        TransformerFactory tf = new TransformerFactory();
        
        XMLTransformer  xt = new XMLTransformer();
        System.out.println(tf.getTransformer(xt));
        
        NetworkTransformer nt = new NetworkTransformer();  
        System.out.println(tf.getTransformer(nt));
        
        
    }
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

Please google Factory pattern to see what I meant.
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

Oh, so is not just a clever wording in a sentence! I'll rewrite the factory part.

By the way, considering when I googled it, how many different books out there have details about Factory pattern in Java, I think this book is missing at least some sort of outline, if not a subsection, about this subject.

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

Factory pattern is not required for OCAJP at all. But because you used the word factory in TransformerFactory and this discussion was veering a bit towards that, I suggested you to read about it. As you found out, there are tons of articles about it. No point in me reinventing the wheel here :)
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

I came across a study that suggested that using enums is most maintainable way to approach creating Factory pattern solutions. So I looked into a couple of examples and came up with this solution for exercise 7.

Two bothersome points about this solution:

1. I had to call the method (overridable one to boot!) transform() from the constructors.
2. I still don't have a solution that utilizes the String parameter of the transform method in the exercise 7!

Questions:

1. Without going through Dependency Injection Frameworks, is there a way I can change the flow so that the call to transform method comes out of the constructors?

2. I wonder if the solution to the first question can be accomplished by the answer to the second bothersome point?

So, I would appreciate a few lines of code hinting to a possible solution. After all, I eventually have to get on with this chapter :) Thanks

Code: Select all

import java.io.IOException;

enum TransformerType {
        
    XML, NETWORK
}

abstract class Transformer {
    
    final private TransformerType tType;
    
    public Transformer(TransformerType tType) {
        this.tType = tType;
    }
    
    public TransformerType getTransformerType() {
        return tType;
    }
    
    abstract void transform () throws IOException;
}

class XMLTransformer extends Transformer {
    
    XMLTransformer() {
        super(TransformerType.XML);
        transform();
    }
    
    @Override
    public void transform(){
        System.out.println("xmldata.");
    }
}

class NetworkTransformer extends Transformer {
    
    NetworkTransformer() throws IOException{
       super(TransformerType.NETWORK);
       transform();
    }    
    
    @Override
    public void transform () throws IOException {
        System.out.println("data from network.");
    }
}

class TransformerFactory {
    
    public static Transformer getTransformer(TransformerType x) throws IOException{
        
        Transformer t = null;
        
        switch(x){
            
            case XML : t = new XMLTransformer(); break;
            
            case NETWORK : t = new NetworkTransformer(); break; 
            
            default: throw new IOException("Bad request.");
        }
        return t;
    }
      
    
    public static void main (String[] ...args) throws IOException{
        
        TransformerFactory.getTransformer(TransformerType.XML);
         
        TransformerFactory.getTransformer(TransformerType.NETWORK);
           
    }
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

The transform method should take a String argument. This is the input that it has to transform!
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

Just so I'm clear - Are you saying to get rid of the enum all together or change the enum to String to pass to transform method? Even so, how does that gets calling transform method out of the constructors?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

Please read the problem statement carefully. I am talking about the transform method not the getTransformer method.
Here is the code:

Code: Select all


abstract class Transformer{
  public String transform(String data) throws Exception;
}

class XMLTransformer extends Transformer{
public String transform(String data) {
   return "data".toUpperCase(); //or whatever transformation is required
}

class TransformerFactory{
  Transformer getTransformer(String or enum parameter){
     return new XMLTransformer or some other transformer depending on parameter 
  }
}

class TestClass{
   pvsm{
      Transformer t =  TransformerFactory.getTransformer("xml" or enum);
      t.transform("the data you want to transform");
   }
}
That's pretty much it.

Could you please leave a review of the book on Amazon? Here is the link:

https://www.amazon.com/s?k=enthuware&ta ... nb_sb_noss

We would really appreciate it. thank you.
If you like our products and services, please help us by posting your review here.

OCAJO1
Posts: 221
Joined: Mon Nov 26, 2018 2:43 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by OCAJO1 »

Could you please leave a review of the book on Amazon? Here is the link:

https://www.amazon.com/s?k=enthuware&ta ... nb_sb_noss
Of course, I am planning to that after I finished with chapter 12 anyway.

I believe that I have a code that incorporates your code hints and what I've picked up about enum to satisfy exercise 7. What do you think?

Code: Select all

enum TransformerType {
        
    XML, NETWORK
}

abstract class Transformer {
    
    abstract void transform (String Data) throws IOException;
}

class XMLTransformer extends Transformer {
        
    @Override
    public void transform(String Data){
        System.out.println(Data);
    }
}

class NetworkTransformer extends Transformer {
      
    @Override
    public void transform (String Data) throws IOException {
        System.out.println(Data);
    }
}

class TransformerFactory {
    
    public static Transformer getTransformer(TransformerType x) throws IOException{
        

        switch (x) {
            case XML:
                return new XMLTransformer();
            case NETWORK:
                return new NetworkTransformer();
            default:
                throw new IOException("Bad request.");
        }
    }
}

class TestClass {

    public static void main(String[] args) throws IOException {

        Transformer tr;
        
        tr = TransformerFactory.getTransformer(TransformerType.XML);
        tr.transform("xmldata."); 
         
        tr = TransformerFactory.getTransformer(TransformerType.NETWORK);
        tr.transform("data from network.");
        
        /*or for those who are concerned with saving stackflow memory
        
        TransformerFactory.getTransformer(TransformerType.XML).transform("xmldata.");
        TransformerFactory.getTransformer(TransformerType.NETWORK).transform("data from network.");
        
        */

    }
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

Yes, this is good :thumbup:
If you like our products and services, please help us by posting your review here.

zeldalex
Posts: 3
Joined: Sun May 12, 2019 8:32 am
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by zeldalex »

For question 5, the following code won't be able to print calories based on actual type of pie, it will only refer to the static method at the superClass and always print 100.

Code: Select all

class Pie{
    public void makePie(){
        System.out.println("making pie");
    }

    public static int getCalories(){
        return 100;
    }
}

class PumpkinPie extends Pie{
    public void makePie(){
        System.out.println("making PumpkinPie");
    }

    public static int getCalories(){
    return 200;
    }
}

class ApplePie extends Pie{
    public void makePie(){
        System.out.println("making ApplePie");
    }

    public static int getCalories(){
    return 300;
    }
}

class Nutritionist{
    void printCalories(Pie p){
        System.out.println(p.getCalories());
    }
}
It will works fine with the instanceof + casting

Code: Select all

class Nutritionist{
    void printCalories(Pie p){
        if (p instanceof ApplePie)
        System.out.println(((ApplePie)p).getCalories());
        if (p instanceof PumpkinPie)
        System.out.println(((PumpkinPie)p).getCalories());
    }
}

But as I learnt from the book, the getCalories() in subClass shall hide the one in superClass, in this case the hiding(or shadow?) seems not working, and I don't think the combine of instanceof and casting is a good solution, may I know what's the problem with my code?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: HD Pg 324, Sec. 11.6.0 - exercises

Post by admin »

There is nothing wrong with the code. p.getCalories(); (as shown in your first Nitritionist class), will indeed invoke Pie's static method.

Your task is to solve the issue. You can try various approaches. Your second Nutrition class is one solution. There is no restriction.
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 34 guests