我正在尝试实现装饰模式,我的问题是我有不同的生成源将传递给装饰的掩码,我没有公共的父暴露我需要的方法在每个掩码中进行各种掩码所以要解决这个问题我考虑过将类型传递给masker,每个masker都会知道他将使用的setter / getter,现在我要做的就是传递具有公共父级(没有方法)的对象并使用它们来构建这些对象传递的类型,现在我的问题是调用getter,例如对于NumbrMasker我知道getter / setter将是getNumber / setNumber但是我不知道如何调用传递类型的方法。
class NumberDecoratedMasker extends Masker {
private Class classType;
public DecoratedMasker (Masker masker, Class classType) {
this.classType = classType;
}
//for Number masker
public void mask(ParentModel parent) {
//cast parent using classtype
//call getNumber/setNumber for masking number
if(masker != null)
makser.mask(parent); // this is the decorated call for the other masker in the decorator structure
}
}
class ParentModel {
//has nothing
}
class Elementa extends ParentModel {
//has setters and getters for number
}
现在我使用我要屏蔽的对象的classType初始化Decorative
Masker masker = new NumberDecoratedMakser(new SecondNumberDecoratedMasker(ElementA.class), ElementA.class);
ParentModel model = new ElementA();
masker.mask(moel);
我知道在这种情况下反射将是一个解决方案,但我不能顺其自然,有没有办法用java8做到这一点?
答案 0 :(得分:3)
""" Django settings for maths project. Generated by 'django-admin startproject' using Django 1.11.11. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'i$*nj0(qn4&b402jjag@ql3#*z@^9(axmay=7s+b6t(h8cpym9' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'students', 'commons', 'community', 'chapters', 'assignment', 'search', 'courses', 'cart', 'orders', 'billing', 'addresses', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'maths.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'maths.wsgi.application' AUTH_USER_MODEL = 'students.User' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'maths', 'USER': 'root', 'PASSWORD': 'ishwar', 'HOST': 'localhost', 'PORT': '3306', } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Asia/Kolkata' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static_my_proj"), ] STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_cdn", "static_root") MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_cdn", "media_root") LOGIN_REDIRECT_URL = 'students:login' LOGIN_URL = 'chapters:list' LOGOUT_REDIRECT_URL = 'students:unlogged' EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
使用类需要丑陋之类的内容,如:
interface Xetter<T> {
void set(T x);
T get();
}
public void mask(ParentModel parent, Class<Xetter<ParentModel>> xetter) {
}
最好使用JavaFX中使用的...属性类,例如StringProperty
。这包装了一个值类型/类,并提供了您正在寻找的抽象。请看WritableValue
。
作为最后一句话。通常,应该使用参数化的类,如:
public <T> T f(Class<T> type, Object value) {
return type.cast(value);
}
反馈后: 仍然不太确定符合预期行为的装饰。
class Value {
}
class NumberValue extends Value {
private Number number;
void setNumber(Number number) {
this.number = number;
}
Number getNumber() {
return number:
}
}
class Masker {
public void mask(Value value) {
}
}
无论
class NumberDecoratedMasker<T extends NumberValue> extends Masker {
private final Masker masker;
private final Class<T> type;
public NumberDecoratedMasker(Masker masker, Class<T> type) {
this.masker = masker;
this.type = type;
}
//for Number masker
public void mask(Value value) {
//cast parent using classtype
//call getNumber/setNumber for masking number
NumberValue n = type.cast(value);
n.setNumber(42 + n.getNumber);
value = n;
if (masker != null) {
masker.mask(value);
}
}
}
Masker masker = new NumberDecoratedMasker(
new SecondNumberDecoratedMasker<NumberValue>(NumberValue.class), NumberValue.class);
或
class NumberDecoratedMasker extends Masker {
private final Masker masker;
private final Class<NumberValue> type;
public NumberDecoratedMasker(Masker masker, Class<NumberValue> type) {
this.masker = masker;
this.type = type;
}
//for Number masker
public void mask(Value value) {
//cast parent using classtype
//call getNumber/setNumber for masking number
NumberValue n = type.cast(value);
n.setNumber(42 + n.getNumber);
value = n;
if (masker != null) {
masker.mask(value);
}
}
}
Masker masker = new NumberDecoratedMasker(
new SecondNumberDecoratedMasker(NumberValue.class), NumberValue.class);
Value model = new NumberValue();
masker.mask(model);