Существует некоторый класс User в котором описан метод IsValidUser(login, password). В реализации метода необходимо подключаться к БД и опеределять существует ли пользователь с параметрами логин и пароль.
Необходимо реализовать класс так, чтобы его можно было повторно использовать и в других приложениях. Но в других приложениях может измениться имя таблицы и/или имена полей в таблице.
Возникли затруднения с самой его реализацией и на ум проходят два выхода, между которыми не могу сделать выбор.
1. В других приложениях описывать какой-то дочерний класс от User и в новом классе переопределять метод IsValidUser, но тогда толку от реализации логики в базовом классе, если его все равно придется переписать.
2. В каком-то конфиг-классе или в настройках приложения или в настройках "первого запуска приложения" (не столь важно) указывать имя таблицы пользователей и имена полей login и password. И в реализации метода использовать именно эти значения.
Класс User взят в качестве примера, в библиотеке может быть большое количество классов реализованных по такому-же принципу. Даже в этом же классе, например методы: IsExist(login), IsActive(user_id) и т.п.
Здравствуйте, Kalastiuz, Вы писали:
K>Существует некоторый класс User в котором описан метод IsValidUser(login, password). В реализации метода необходимо подключаться к БД и опеределять существует ли пользователь с параметрами логин и пароль. K>Необходимо реализовать класс так, чтобы его можно было повторно использовать и в других приложениях. Но в других приложениях может измениться имя таблицы и/или имена полей в таблице. K>Возникли затруднения с самой его реализацией и на ум проходят два выхода, между которыми не могу сделать выбор. K>1. В других приложениях описывать какой-то дочерний класс от User и в новом классе переопределять метод IsValidUser, но тогда толку от реализации логики в базовом классе, если его все равно придется переписать. K>2. В каком-то конфиг-классе или в настройках приложения или в настройках "первого запуска приложения" (не столь важно) указывать имя таблицы пользователей и имена полей login и password. И в реализации метода использовать именно эти значения.
K>Класс User взят в качестве примера, в библиотеке может быть большое количество классов реализованных по такому-же принципу. Даже в этом же классе, например методы: IsExist(login), IsActive(user_id) и т.п.
Почему методы IsValidUser, IsExist и IsActive что-то принимают? Они статические? Или класс User на самом деле не то чем кажется?
public class User {
public User(IUserProvider provider, int id) {
this.id = id;
this.provider = provider;
}
public boolean isValid(String password) {
return provider.isValid(id, password);
}
public boolean isActive() {
return provider.isActive(id);
}
}
public class MyDatabaseUserProvider implements IUserProvider {
public DatabaseUserProvider(Properties properties) {
this.usersTable = properties.getString("usersTable");
this.nameColumn = properties.getString("nameColumn");
this.passwordColumn = properties.getString("passwordColumn");
}
}
class UserBase
{
// и в медодах класса используй это поле
private DBConf conf;
public UserBase(DBConf config)
{ ... }
public bool IsValidUser(login, password)
{ ... }
}
class DBConf
{
public string TableName {get;set;}
public string LoginColumnName {get;set;}
public string PasswordColumnName {get;set;}
// и другие необходимые настройки
// этот метод можно переопределить, чтоб получать
// настройки в одном приложении например из Базы1,
// а в другом из Базы2, а в третем из файла
public virtual void Init (string connectionString)
{
...
// сдесь получаешь настройки из файла, базы (откуда хочешь)
...
}
}
Здравствуйте, komaz, Вы писали:
K>Почему методы IsValidUser, IsExist и IsActive что-то принимают? Они статические? Или класс User на самом деле не то чем кажется?
Могут быть и методы без параметров, а можно перегрузить и так так. А можно в конструкторе инициализировать объект данными о логине и пароле. Это не столь важно.
Важно понять идею и то как же все таки правильнее реализовать, что бы в последствии можно было использовать классы повторно.
В случае если я опишу метод следующим образом:
public Boolean IsValidUser(String login, String password)
{
...
String query = @"SELECT user_id FROM tbl_users WHERE tbl_users.login = @login AND tbl_users.password = @password";
...
}
То какова вероятность того, что пользователь назовет таблицу и имена полей именно так, а не например users? Крайне мала.
Значит привязывать запрос к определенной таблице/полям не совсем правильно. А если пользователю придется переопределять метод в дочернем классе, то тогда можно оставить тело метода пустым. Пусть переопределяет как хочет. Такой вариант, тоже не особо нравится.
С другой стороны, если в каком-то конфиге сопоставить данные о таблице и ее полях. Получится громоздкий конфиг файл. Таблица пользователей же не одна да и полей можно быть какое-то количество.
Как вариант еще с библиотекой классов поставлять некий скрипт, создающий таблицы используемые в ней, автоматически с теми названиями которые удобны мне, как разработчику данных классов.
Вот и пробую найти наиболее удачное решение.
Сделай класс самым очевидным образом, а потом попробуй покрыть его юнит тестами. Скорее всего, что бы сделать это, классс придется рефакторить. А результат, скорее всего, уже можно будет повторно использовать.
Или вообще, попробуй TDD.
Здравствуйте, Kalastiuz, Вы писали:
K>Важно понять идею и то как же все таки правильнее реализовать, что бы в последствии можно было использовать классы повторно.
Классы повторно можно, а вот метод IsValidUser — вряд ли, как ты уже сам докадался.
K>Вот и пробую найти наиболее удачное решение.
Наиболее удачное решение — вынести методы тип IsValidUser и всю логику завязанную на конкретное окружение во внешние классы. Например, метод IsValidUser — должен принадлежать не классу User, а конкретной подсистеме аутентификации, где вообще никакого SQL-я может не быть, а быть, например AD, или вообще что-то смешанное.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[4]: Проектирование класса на примере User
От:
Аноним
Дата:
13.07.09 17:50
Оценка:
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, Kalastiuz, Вы писали:
K>>Важно понять идею и то как же все таки правильнее реализовать, что бы в последствии можно было использовать классы повторно. IB>Классы повторно можно, а вот метод IsValidUser — вряд ли, как ты уже сам докадался.
K>>Вот и пробую найти наиболее удачное решение. IB>Наиболее удачное решение — вынести методы тип IsValidUser и всю логику завязанную на конкретное окружение во внешние классы. Например, метод IsValidUser — должен принадлежать не классу User, а конкретной подсистеме аутентификации, где вообще никакого SQL-я может не быть, а быть, например AD, или вообще что-то смешанное.
Полностью поддерживаю. Валидаторов может быть много, и разных, а класс User — всё тот же.
Причем валидировать можно даже не один класс, а консистентность сочетаний: например, валидация связки User и Car будет задавать вопрос: почему у юзера с зарплатой в сто тугриков в гараже стоят Ламборджини и Майбах