(Полиморфизм) Передача параметра добавления в конструктор производного класса в шаблоне фабрики - PullRequest
0 голосов
/ 19 ноября 2018

В фабричном шаблоне мы используем класс Factory для создания класса Product, который реализует Abstract Product.

interface AbstractProduct {
     public string getDetail();
}

class Product_A : AbstractProduct {
     public string getDetail();
}

class Product_B : AbstractProduct {
     public string getDetail();
}

class Factory {
     public AbstractProduct produce(int product_id){
          if (product_id == 1){
                return Product_A();
          }
          else if (product_id == 2){
                return Product_B();
          }
     }
}

int main() {
     Factory factory = new Factory();
     int id; // a random number either 1 or 2

     print(factory.produce(id).getDetail());
}

Мой вопрос таков: что если сегодня нам нужно извлечь информацию для передачи в Product_B из main(), например, ссылку на экземпляр класса.

int main() {
     // object that need to be passed into Product_B
     Database database = new Database();

     Factory factory = new Factory();
     int id; // a random number either 1 or 2

     print(factory.produce(id).getDetail());
}

class Product_B : AbstractProduct {
     public string getDetail() {
         // I need the reference of database here.
         // I'm unable to instance a database in side Product_B.
         // I need to somehow pass it into Product_B.
         database.query();
     }
}

Единственное решение, которое приходит мне в голову, это ...

class Factory {
     // pass the reference here
     public AbstractProduct produce(int product_id, Database db){
          if (product_id == 1){
                return Product_A();
          }
          else if (product_id == 2){
                return Product_B(db);
          }
     }
}

Есть ли какое-нибудь хорошее решение или соответствующий шаблон дизайна, способный решить эту проблему Элегантный и Чистый ? Большое спасибо.

1 Ответ

0 голосов
/ 20 ноября 2018

Недостатком вашего решения является то, что каждый клиент Factory должен иметь Database для вызова метода produce.

Таким образом, вы можете использовать шаблон Abstract Factory здесь:

interface AbstractFactory {
    AbstractProduct produce();
}

class Factory_A implements AbstractFactory {
    AbstractProduct produce() { return new Product_A(); }
}

class Factory_B implements AbstractFactory {
    private Database db;
    public Factory_B(Database db) { this.db = db; }
    AbstractProduct produce() { return new Product_B(db); }
}

class Client {
    private AbstractFactory factory;
    public Client(AbstractFactory factory) { this.factory = factory; }
    public void foo() {
        AbstractProduct product = factory.produce();
        // ...
    }
}

void main() {
    AbstractFactory factory = random() == 1 ?
                                new Factory_A() :
                                new Factory_B(new Database(...));

    print(factory.produce().getDetail());

    Client client = new Client(factory);
    client.foo();
}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...