Я столкнулся с той же проблемой в дочерних компонентах, где изначально она должна была иметь текущее значение Субъекта, а затем подписаться на Субъект для прослушивания изменений. Я просто поддерживаю текущее значение в Сервисе, поэтому оно доступно для доступа к компонентам, например. :
import {Storage} from './storage';
import {Injectable} from 'angular2/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class SessionStorage extends Storage {
isLoggedIn: boolean;
private _isLoggedInSource = new Subject<boolean>();
isLoggedIn = this._isLoggedInSource.asObservable();
constructor() {
super('session');
this.currIsLoggedIn = false;
}
setIsLoggedIn(value: boolean) {
this.setItem('_isLoggedIn', value, () => {
this._isLoggedInSource.next(value);
});
this.isLoggedIn = value;
}
}
Компонент, который нуждается в текущем значении, может просто получить к нему доступ из службы, то есть:
sessionStorage.isLoggedIn
Не уверен, что это правильная практика :)
Можно сделать sub дочерние классы классов, что-то вроде этого:
public abstract class AbstractClass
{
public static AbstractClass MakeAbstractClass(string args)
{
if (args == "a")
return new ConcreteClassA();
if (args == "b")
return new ConcreteClassB();
}
private class ConcreteClassA : AbstractClass
{
}
private class ConcreteClassB : AbstractClass
{
}
}
@Vaibhav Это действительно означает, что классы также скрыты. Но это - насколько я знаю единственный способ полностью скрыть конструктора.
Править: Поскольку другие упомянули, что то же самое может быть выполнено с помощью Отражения, которое могло бы на самом деле быть ближе к тому, что требуется иметь место - например, вышеупомянутые ответы метода на реальные классы, являющиеся в том же файле как Абстрактный класс, который, вероятно, не очень удобен. Сказав, что этим путем является хороший 'Взлом', и хороший, если число и сложность реальных классов являются небольшими.
Не можете Вы использовать ключевое слово partial
для разделения кода для класса во многие файлы?
Необходимо ли на самом деле сделать это? При использовании некоторого псевдо шаблона "фабрика" без истинной потребности дизайна в нем Вы только собираетесь сделать свой код тяжелее, чтобы понять, поддержать и расшириться.
Если Вы не должны делать этого, просто реализуйте истинный шаблон "фабрика". Или, больше ALTy, используйте платформу DI/МОК.
Если классы находятся в том же блоке, разве Вы не можете сделать конструкторов внутренними?
При использовании этого класса в отдельном сервисном блоке можно использовать внутреннее ключевое слово.
public class AbstractClass
{
public AbstractClass ClassFactory(string args)
{
switch (args)
{
case "A":
return new ConcreteClassA();
case "B":
return new ConcreteClassB();
default:
return null;
}
}
}
public class ConcreteClassA : AbstractClass
{
internal ConcreteClassA(){ }
}
public class ConcreteClassB : AbstractClass
{
internal ConcreteClassB() {}
}
При следовании за принятым ответом, если Вы имели открытый интерфейс и заставили частные классы реализовать интерфейс, Вы могли бы затем возвратить указатель на интерфейс, и любой за пределами Вашего родительского абстрактного класса мог затем использовать их (все еще скрывая дочерние классы).
Мне простое решение состоит в том, чтобы сделать дочерние классы как samjudson упомянутыми. Я хотел бы избежать этого однако, так как это сделает файл моего абстрактного класса намного больше, чем я хотел бы, чтобы это было. Я не пустил бы разделение классов по поводу нескольких файлов для организации.
Без проблем, просто используйте частичное ключевое слово, и можно разделить внутренние классы на столько файлов, сколько Вы желаете. Вы не должны сохранять его в том же файле.
Предыдущий ответ:
Это возможно, но только с отражением
public abstract class AbstractClass
{
public static AbstractClass MakeAbstractClass(string args)
{
if (args == "a")
return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassA), true);
if (args == "b")
return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassB), true);
}
}
public class ConcreteClassA : AbstractClass
{
private ConcreteClassA()
{
}
}
public class ConcreteClassB : AbstractClass
{
private ConcreteClassB()
{
}
}
и вот другой шаблон, без ужасного MakeAbstractClass (представьте args в виде строки),
public abstract class AbstractClass<T> where T : AbstractClass<T>
{
public static T MakeAbstractClass()
{
T value = (T)Activator.CreateInstance(typeof(T), true);
// your processing logic
return value;
}
}
public class ConcreteClassA : AbstractClass<ConcreteClassA>
{
private ConcreteClassA()
{
}
}
public class ConcreteClassB : AbstractClass<ConcreteClassB>
{
private ConcreteClassB()
{
}
}
То, что необходимо сделать, это для предотвращения конструктора по умолчанию, чтобы быть создает. Внутренним может быть изменение в общественности, если классы не находятся в том же блоке.
public abstract class AbstractClass{
public static AbstractClass MakeAbstractClass(string args)
{
if (args == "a")
return ConcreteClassA().GetConcreteClassA();
if (args == "b")
return ConcreteClassB().GetConcreteClassB();
}
}
public class ConcreteClassA : AbstractClass
{
private ConcreteClassA(){}
internal static ConcreteClassA GetConcreteClassA(){
return ConcreteClassA();
}
}
public class ConcreteClassB : AbstractClass
{
private ConcreteClassB(){}
internal static ConcreteClassB Get ConcreteClassB(){
return ConcreteClassB();
}
}