#java
#java
Вопрос:
Нормально ли передавать тип объекта или просто тип любого вида в конструктор нового объекта, а затем не использовать его внутри конструктора?
Цель состоит в том, чтобы создать новый объект на основе того, в каком родительском классе он находится (он агрегирован), чтобы он генерировал разные переменные для себя на основе этого факта.
Или есть лучший способ сделать это?
public class ObjectA {
private MalleableObject obj;
public void createObject(){
obj = new MalleableObject(this);
}
}
public class ObjectB {
private MalleableObject obj;
public void createObject(){
obj = new MalleableObject(this);
}
}
public class MalleableObject{
private boolean doIBelongToA;
public MalleableObject(ObjectB obj){
doIBelongToA = false;
}
public MalleableObject(ObjectA obj){
doIBelongToA = true;
}
}
Комментарии:
1. в этом конкретном случае, почему бы не передать логическое значение напрямую вместо класса? В более общем случае, если вы не используете объект, почему бы не передать параметр condition или объект, который вы фактически используете в контроллере?
2. Это допустимо. Итак, есть ли лучший способ сделать то, чего вы хотите достичь (о котором вы нам не сказали), вероятно.
3. Я бы сказал, что это плохая практика, поскольку это сбивает с толку любого, кто пытается понять код.
4. это возможно, но это может привести к проблемам. любой сбой в дальнейшем, когда используется этот экземпляр, тот, кто его использует, может подумать, что он передал недопустимый параметр, в то время как сам параметр бессмыслен.
5. В качестве моей собственной идеи, которая только что возникла, я мог бы также сделать ObjectA и ObjectB производными от общего интерфейса, передать тип интерфейса в качестве параметра, а внутри конструктора MalleableObject я бы проверил, является ли объект экземпляром A или B, и на основе этого установить значения по умолчанию. Это было бы лучше?
Ответ №1:
Используемый вами подход определенно сработает, но вопрос в том, хорошая это идея или нет, ответ зависит от варианта использования, который вы пытаетесь решить.
Вы спрашивали о том, чтобы взять объект в качестве параметра в конструкторе и не использовать его
Если вы не используете свойство переданного параметра, то зачем принимать это в параметре, для этого у нас есть пустой конструктор, даже если вы не указываете, что он по умолчанию введен
public MalleableObject(ObjectB obj){
doIBelongToA = false; // if you are directly setting the value without
//using obj b then use default constructor.
}
public MalleableObject(ObjectA obj){
doIBelongToA = true;
}
/*If you are interested in setting the value based on the reference only there
is no problem with your approach as well, One alternative you can take to
combine both of them in single constructor and check the reference and set
the value accordingly*/
Если вы используете свойство объекта для создания нового объекта, то, безусловно, это хорошая идея,
Скопируйте конструктор, если вы используете тот же объект в качестве параметра, шаблон проектирования прототипа, если вы создаете свой объект с уже созданным аналогичным объектом
Приведенный вами пример является очень простым примером, который не выделяет какой-либо вариант использования, и, следовательно, выбранный вами подход не будет предложен
Ответ №2:
Более простым подходом было бы просто добавить логическую переменную в конструктор MalleableObject .
public class ObjectA {
private MalleableObject obj;
public void createObject(){
obj = new MalleableObject(true);
}
}
public class ObjectB {
private MalleableObject obj;
public void createObject(){
obj = new MalleableObject(false);
}
}
public class MalleableObject{
private boolean doIBelongToA;
public MalleableObject(boolean doIBelongToA){
this.doIBelongToA = doIBelongToA;
}
}
Это легко гарантировало бы, что объект, созданный из класса A, имеет значение true для doIBelongToA.
Кроме того, вам не придется добавлять разные конструкторы для дальнейших классов, если они будут добавлены, обеспечивая расширяемость
Комментарии:
1. Это очевидный способ обработки, но вопрос скорее в том, является ли это лучшей идеей или нет
2. В вопросе также задается вопрос о лучшем способе сделать это
3. Вы должны прокомментировать проблему с текущим подходом, затем описать лучший подход и, пожалуйста, включить фрагмент кода, как конструктор может быть вызван на основе ссылки на объект
Ответ №3:
Хотя вы не используете его напрямую, вы определенно используете информацию из параметра. Лично я бы сохранил ссылку или, по крайней мере, ее тип для последующего использования на случай, если вам это понадобится, и реализовал doIBelongToA
как метод, но в вашем подходе нет ничего технически неправильного:
public class MalleableObject{
private Class ownerType;
public MalleableObject(Class ownerType) {
this.ownerType = ownerType;
}
public boolean doBelongToA() {
return ownerType.equals(ObjectA.class);
}
}
Комментарии:
1. Выполнение
Class
проверки равенства легко приведет к проблеме нарушения принципа подстановки Лискова. Немного лучшим выбором может бытьObjectA.class.isAssignableFrom(ownerType)
Ответ №4:
Описанный выше подход работает, но это не лучшая практика и, следовательно, имеет некоторые ограничения. Я бы посоветовал вам использовать шаблон builder, где вы можете использовать builder для создания объекта, а затем иметь метод, который определяет поведение. В будущем вы сможете расширить это, чтобы добавить переменные / бизнес-логику.
Я думаю, что на шаблон Factory также стоит обратить внимание
Комментарии:
1. Как шаблон builder может подойти для этого варианта использования?, Для этого можно изучить шаблон Factory, но это не так близко к решению заданного вопроса, было бы еще лучше привести какой-нибудь фрагмент кода, объясняющий вашу точку зрения