Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
So because I'm currently reading into design patters I have a "newbie" and at least for me interesting question to ask.
What Factory implementation is the best? I've seen factories where the create method is hardcoded and if a new subtype is added I'll need to edit the method. For example:
public class ProductFactory{
public Product createProduct(String ProductID){
if (id==ID1)
return new OneProduct();
if (id==ID2) return
return new AnotherProduct();
... // so on for the other Ids
return null; //if the id doesn't have any of the expected values
}
...
}
This seems to be the implementation that takes the lowest amount of resources. But furthemore I've seen implementations that use reflection:
class ProductFactory
{
private HashMap<String, Class> m_RegisteredProducts = new HashMap<>();
public void registerProduct (String productID, Class productClass)
{
m_RegisteredProducts.put(productID, productClass);
}
public Product createProduct(String productID)
{
Class productClass = (Class)m_RegisteredProducts.get(productID);
Constructor productConstructor = cClass.getDeclaredConstructor(new Class[] { String.class });
return (Product)productConstructor.newInstance(new Object[] { });
}
}
Which seems to be the slowest one because it is using reflection to work. And the last implementation seems to take the most RAM because it has an extra instance of a specific class stored.
class ProductFactory
{
private HashMap<String, Product> m_RegisteredProducts = new HashMap<>();
public void registerProduct(String productID, Product p) {
m_RegisteredProducts.put(productID, p);
}
public Product createProduct(String productID){
((Product)m_RegisteredProducts.get(productID)).createProduct();
}
}
Product classes for the last factory:
abstract class Product
{
public abstract Product createProduct();
...
}
class OneProduct extends Product
{
...
static
{
ProductFactory.instance().registerProduct("ID1", new OneProduct());
}
public OneProduct createProduct()
{
return new OneProduct();
}
...
}
Both the second last and last implementation allow to register new products without modifying the factory class in for example a static block in the to be registered product extending/implementing class. Is this better? And if so, which of those two implementation is the better one? Or is the hard coded implementation better because it seems to require less resources.
Approach 1) Parametrized Factory implementation. Overtime we create a new Product object we have to modify the Factory.
Approach 2) We dont need to modify the Factory in order to add a new implementation. In addition the factory needs to know in advance all the available classes in order to begin instantiating them. Performance is not a factor here because on a modern JVM the performance loss from reflection will be negligible.
Approach 3)If I understand correctly the Product is exposing a factory method. Each implementation of Product through Polymorphism is responsible for providing logic for instance creation. Although I dont get it how you will use exactly a non static method. And if you use static you loose your Polymorphism. Approach 3 is not very clear to me. Is the Product actually a Wrapper around the real Product ?
Approach number 1 is least flexible
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am new to Java OOP and have been studying about this reading a GitBook called AP Computer Science in Java
I found this page very confusing:https://codehs.gitbooks.io/apjava/content/Classes-And-Object-Oriented-Programming/class-design-and-abstract-classes.html
the code is like this
public abstract class VehicleClass {
private String type;
private String vehicleName;
public VehicleClass(String vType, String vName) {
type = vType;
vehicleName = vName;
}
/* This will need to be abstract, since
* we will need to implement different formulas
* depending on if the vehicle is electric or
* gas powered.
*/
public abstract double getMileage();
}
/* As you can see, in both classes, we have `getMileage` implemented
* with different formulas.
*/
public class Truck extends VehicleClass {
private double gasTankCapacity;
private double milesPerTank;
public Truck(double capacity, double miles) {
gasTankCapacity = capacity;
milesPerTank = miles;
}
public double getMileage() {
return milesPerTank/gasTankCapacity;
}
}
public class ElectricCar extends VehicleClass {
private double maxCharge;
private double milesPerCharge;
private double maxEnergyUsage;
public ElectricCar(double charge, double maxEnergy, double milesCharge) {
maxCharge = charge;
maxEnergyUsage = maxEnergy;
milesPerCharge = milesCharge;
}
public double getMileage() {
return (maxCharge*milesPerCharge)/maxEnergyUsage;
}
}
MY questions are:
1. Why does he build the constructor of the two child classes without using super(). Doesn't he need to pass type and vehicleName to the super-class's constructor?
2. Why does he make type and vehicleName in the super-class to be private? I know that child class cannot inherit instances variables from the super class. Why doesn't he use protect instead?
You are totally right! That code will not compile.
It's hard to say without knowing the purpose of those variables and of the class.
You're right, and it doesn't compile for that reason.
You may only omit parameterless calls to super, if there is such a constructor in the super class, in which case it is automatically inferred.
Speculation about the reason: The author wanted to show something else (as stated in the comments), maybe first had a working solution but then decided, that the vtype code bloated the example too much up and removed it, without testing again.
To Q.2, why does he make type and vehicleName in the superclass to be private?
I would say, you inherit instance variables, private or not, you just don't have direct access to them.
Why doesn't he use protect instead?
We can't tell. Since it is only demo code, and the private members aren't used and not accessible via getter or setter, we just can't tell. Maybe it is an example which is later extended and then they get used?
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Most of expert programmer here have down voted my answer as bad answer
How to add a field to an ArrayList from a different class?
So, I wonder why do I need to create another function Add to add items to my list. While most of programming language such as Java C# and VB.NET allow us a very simple way by using Getter as a List or ArrayList that we be able to add and use many function that this class has directly as sample as bellow
C#
class Program
{
static void Main(string[] args)
{
Employee emp = new Employee();
emp.lst.Add("Hello");
}
}
class Employee
{
private List<string> _lst = new List<string>();
public List<string> lst
{
get { return _lst; }
}
//public void add(String item) {
// _lst.Add(item);
//}
}
Java
public class MainApp {
public static void main(String[] args){
Employee emp = new Employee();
emp.getLst().add("My String");
}
}
class Employee{
private List<String> lst = new ArrayList<String>();
public List<String> getLst() {
return lst;
}
public void setLst(List<String> lst) {
this.lst = lst;
}
}
Most of languages are allow us to do this ways. So, what is the reason I need to create function Add for on Employee?
Practical reason: getList() may return either internal list or copy of that list. There is no way for consumer of the class to know what is the behavior of the method without knowing implementation of getList() (or less likely find and read documentation on that particular method of particular class). So adding to or modifying result of getList() call in any other way may never change the original object and proving correctness will require reading all the code including (frequently private) implementation of getList().
Whether it is useful to expose separate methods to add to the list or not is personal choice based on particular code. Generally it is better to provide specific methods for all operations on the object as one can guarantee consistency of the state of the object.
For example if object is plain data transfer object having raw lists is fine there, but if it is Student exposing modifiable list of classes may easily lead to inconsistent state if for example total score class is stored independently.
I'm new to OOP and learning design patterns so I wrote some simple code to try out a Factory Method, and all seems well, except when I want to add another sub-type. Here's the code so far:
public interface Person {
public String getDescription();
}
public class Adult implements Person {
#Override
public String getDescription() {
return "I am an ADULT";
}
}
public class Child implements Person {
#Override
public String getDescription() {
return "I am a CHILD";
}
}
public class PersonFactory {
public Person create(int age) {
if (age < 18) return new Child();
return new Adult();
}
}
public class ClientA {
public static void main(String[] args) {
PersonFactory personFactory = new PersonFactory();
Person person;
person = personFactory.create(80);
System.out.println(person.getDescription());
}
}
If the requirement changes later to include a sub-class Pensioner for when the age is > 70, I would have to either:
Add the line if (age > 70) return new Pensioner(); to the create() method in the PersonFactory class, which surely breaks the Open-Closed Principle?
Or, as suggested in The Gang Of Four Design Patterns book, override the parameterized factory method to selectively extend the products a Creator produces. In this case I think that would mean writing a new class:
public class PersonFactoryWithPensioner extends PersonFactory {
#Override
public Person create(int age) {
if (age > 70) return new Pensioner();
return super.create(age);
}
}
This now means that either all the clients which call the PersonFactory would now have to be changed to use PersonFactoryWithPensioner instead, or I have to accept that new clients could call PersonFactoryWithPensioner whilst the old clients eg. ClientA would still only receive an Adult object when the age is > 70. It gets even worse if later on another sub-class eg. Infant is added. To ensure the new clients receive whichever object of Infant, Child, Adult or Pensioner is appropriate, a new class PersonFactoryWithInfant would have to extend PersonFactoryWithPensioner. This can't be right, seems more likely I have misunderstood what GoF suggest.
My question is: Is there a way to add a new sub-type that can be returned to old clients without changing them, and without breaking the OCP by changing the PersonFactory code to include the new sub-type?
Apologies if I have not posted this correctly, it is my first time posting a question here. I have looked through previous answers for similar problem but they don't seem to quite address this.
I think OCP doesn't stop from from modifying any method or class.
But, it proposes that if you need to do any modication, you should do it so that you don't have to modify that code again.
Given that you may need to modify PersonFactory later - you could create yet another Factory class to create objects of type PersonFactory. Although this seems like over-engineered solution.
Another possible solution would be that PersonFactory load this rules from some dynamic source, for example, save this rules in a file using JSON format.
And then create objects dynamically using reflection.
Something like this:
private static JSONObject RULES;
static {
RULES= JSON.parse(rulesEngine.load());
}
public class PersonFactory {
public Person create(int age) {
String personToCreate = RULES.get(age);
Constructor<?> ctor = Class.forName(personToCreate).getConstructor();
return (Person) ctor.newInstance();
}
}
The json rules would be something like this:
{
"1":"Child.class",
"2":"Child.class",
...,
"17":"Child.class",
"18":"Adult.class",
...,
"69":"Adult.class",
"70":"Pensioner.class"
}
This way you don't break OCP Principle.
The open-closed principle is good to keep in mind. It does not work nicely with factories, however. One option that sort-of-works is the following, which turns the factory into a registry:
PersonFactory pf = new PersonFactory();
// Java 8 lambdas are great!
pf.register((age) -> age < 18 ? new Child() : null );
pf.register((age) -> age >= 18 ? new Adult() : null );
System.out.println(pf.create(10).getDescription());
Similarly to #alayor's answer, the only way to avoid having to modify the logic of the factory, or having to replace the factory altogether and get everyone to use the new version... is for the factory to get its logic from elsewhere. #alayor gets it from a configuration file; I propose adding it to the factory as part of its initialization (could be done in the factory constructor too; changing it to, say, public PersonFactory(PersonCreator ... rules) ).
Full code:
interface PersonCreator {
Person create(int age);
}
class PersonFactory {
private List<PersonCreator> pcs = new ArrayList<>();
public void register(PersonCreator pc) {
pcs.add(pc);
}
public Person create(int age) {
for (PersonCreator pc : pcs) {
Person p = pc.create(age);
if (p != null) {
return p;
}
}
return null;
}
}
interface Person {
public String getDescription();
}
class Adult implements Person {
#Override
public String getDescription() {
return "I am an ADULT";
}
}
class Child implements Person {
#Override
public String getDescription() {
return "I am a CHILD";
}
}
public class Main {
public static void main(String[] args) {
PersonFactory pf = new PersonFactory();
// Java 8 lambdas are great!
pf.register((age) -> age < 18 ? new Child() : null );
pf.register((age) -> age >= 18 ? new Adult() : null );
System.out.println(pf.create(10).getDescription());
}
}
Rules are sometimes meant to be broken, so I say BREAK the Closed Principle to keep it clean and simple. The overhead of creating multiple Factory Classes for each type of person breaks the entire Factory Method purpose in my opinion. Breaking the Closed Principle allows you to have a single class to create any type of person.
public Person create(int age) {
if (age < 4) return new Infant();
if (age < 18) return new Child();
if (age < 70) return new Adult();
return new Pensioner();
}
All answers here, that suggests some kind of dynamic rules are in fact breaking open-close principle. This principle isn't about "don't change a piece of code that is already written" but "don't change a outcome of code already in use". That said, if a client expects that it only can get two results - Adult or Child then providing third possibility either by hardcoding it into function or by dynamic rulesets is breaking of open-close principle.
But returning to your question - I'll say it depends. Principles and patterns are nice, fun and all but in real day-to-day work one must always look at the big picture and decide if to apply certain rule or not. Treat them as hints, not something that's written in stone.
If your code is somewhat closed, that is you have control of every invocation of PersonFactory, then changes are just normal thing in the lifecycle of your software. I don't recall any real life project I've participated into, that hasn't changed any bit of code created previously. In fact we're doing it on the daily basis :)
Other thing is when your code is used by unknown number of third party clients (public API for example). Then you should be careful not to break something, but also presenting new logic in existing methods (as here when you add new concept of Person) is perfectly acceptable. If those would be breaking changes then consider adding new/upgraded version of changed code alongside old one (and possibly have a plan of deprecating old version sometime in the future as you really don't want to end up maintaining 10000 versions of your code ;)
Also remember about other OOP pieces that should help you avoid some problems. In your example Adult, Child and Pensioner all implements Person interface which is great. So any code that knows only Adult and Child implementations should not have problem with using Pensioner value as all of them are just implementations of Person and that code should treat Pensioner also as Person without even knowing you've introduced a new type.
The question is "do the client expect a Pensioner object to be created without code modification?". If yes, then you should break the "Closed" rule and update you factory code. If not, then you should create a new factory and the clients will use it.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
i have this situation:
public class Number {
int num;
private TakeNumber take = null;
public Number() {
num = 5;
}
public void print() {
take.doSomething();
}
public int getNumber() {
return num;
}
public static void main(String[] args) {
new Number();
}
}
public class TakeNumber {
private Number number = new Number();
public void doSomething() {
System.out.println(number.getNumber());
}
}
Now, can someone explain me these situations:
I want to know what the compiler interprets here : private Number number = new Number();
Initialize the object in question and passing the required methods
Is correct initialize one object to null and then call a function on that object, as shown
in brief
I would like to know if you can call a method of a class of another class:
without the required function to be static
IMPORTANT do not inherit the classes because I want to use methods of these classes, for example:
I have classes that are conceptually different as Tomato and machine, I would call the methods of Machine into Tomato
I would like to know if you can call a method of a class of another class:
without the required function to be static
If the methods are not static, then you will need an instance of that object to call it.
Object o = new Object();
o.doSomething();
Is how you access an instance method.
I have classes that are conceptually different as Tomato and machine, I would call the methods of Machine into Tomato
This is fine. This is called composition. Composition is a has a relationship between classes. A class Man has a class Car, but Is a class Person. And it is perfectly valid to write code as you have shown. This is how you use composition to expose only the interface of a composite object that you want. For example..
public class MyClass extends MyOtherClass
Now you've just exposed the whole interface of MyOtherClass. This might not be desired.
public class MyClass {
MyOtherClass otherClass;
public void doSomething() {
otherClass.doSomething();
}
}
Now, you've only exposed the doSomething() method. This is useful when, as you said, your objects are conceptually different, but require some shared functionality. It is a perfectly valid code practise.
NOTE: Given the confusing nature of your question, I imagine I've missed some stuff out so please comment with desired edits.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
In my DAO i have a method where i build 2 different objects and I want to return both of those objects, but i'm not sure what the best way is to do it. I've looked at using ? extends myObject, creating another class that holds both of my objects that i want to return, and just using List<Object>.
Long story short on why i need these similar objects is to display 1 on the screen and the other to use with primefaces dataexporter which doesn't handle lists in an object as far as i'm aware.
Class Person
public class Person() {
firstName = null;
lastName = null;
List<Programs> programs = new ArrayList<Programs>();
// Getters and setters
}
Class DataExporterPerson
public class DataExporterPerson() {
firstName = null;
lastName = null;
String program = null;
// Getters and setters
}
DAO method:
public List<SOMETHING> getPeople() {
// query db for people
// build both objects
return ?????
}
Now i understand i can very easily create another object like the one below, but that seems like an inefficient way to do things because i'm basically creating an object just to return from 1 method.
public class PersonTransporter() {
Person person = null;
DataExporterPerson = null;
}
What is the best way to handle this scenario?
EDIT
The reason that i'm trying to return 2 objects in 1 method is because this is a DAO method that queries the database and builds 2 objects based on the data in the query. I don't want to break it up into 2 methods because i don't want to query the db twice if i don't need to.
You can either handle this through inheritance, or containment.
You can have Person and DataExporterPerson extend something like AbstractPerson. However, since you have not already done so, then it is probably inappropriate to do inheritance.
I think it was Effective C++ that talked about how containment is better than inheritance. IIRC the reason stated is that containment is more loosely coupled than inheritance.
Here you would have a object that contains both Person and DataExporterPerson. Your method would populate one of those for this union type object, and by seeing which one is null you would know which one you actually have.
public class DBPersonUnion {
private Person person = null;
private DataExporterPerson dataExporterPerson = null;
//getters and setters.
}
If your method need to return two different types this is a hint that there is something wrong with your architecture or method logic.
What you can do ?
Create a class that will logically join the elements,
Introduce common interface that, both class will implement,
Implement two methods fist return with object, that second use a parameter and return the second object.
The example for last point
class Foo {
String f;
}
class Bar {
String b;
}
Then problem how to return object Foo and Bar ?
public Object theProblemMethod() {
Foo a = new Foo();
a.foo = "Test";
Bar b = new Bar();
b.bar = a.foo; //The logic where class Foo meet class Bar.
return ???
}
The valid implementation
public Foo createFoo(){
Foo a = new Foo();
a.foo = "Test";
return a;
}
public Bar createBar(Foo f) {
Bar b = new Bar();
b.bar = f.foo;
reutrn b;
}
Usage
public void action() {
//theProblemMethod(); //This we can not do
Foo a = createFoo();
Bar b = createBar(a);
}
Your actual issue here is one of design. No method should be doing more than one thing: therefore a method that returns two unlike objects is probably bad design. To actually solve this problem, you should break your method into two, separate methods to handle the two different concerns.
However, let us assume you cannot do this. Based on your notes it seems most of your state in the two objects is repeated. You can combine these two by having them inherit from a similar source - but this only solves half your problem. Instead, you can decorate the one with the other:
public class DataExporterPerson {
private Person person;
private String program = null; //or any other
//other getters/setters, esp to get the core 'person' object.
//note that getters/setters for repeated state should just
// pass through to the underlying object:
public String getName() { person.getName(); } //for example
}
If you absolutely must return two objects, you may do this, but it's hard to test and violates the 'no side effect' principle:
public boolean buildThings(ThingA a, ThingB b) {
a = <whatever>;
b = <whatever else>;
return true;//success!
}
//...
//somewhere else in code
ThingA a = null;
ThingB b = null;
boolean result = buildThings(a, b);
//use a and b here
You could do two different things.
The first have the method signature be public List<Object> getPeople(). This will allow you to do instanceof and figure out which is which.
OR
you could have DataExporterPerson extend Person (or make a new class/interface that both DataExporterPerson and Person extend/implements and use that as the type).