如何在不违反 Typescript 中的 OCP 的情况下创建工厂对象
How to create a factory object without violating OCP in Typescript
我刚刚学习了工厂模式并想在 Typescript 中实现它。
我检查了很多站点,例如 this,并注意到所有示例都违反了 OCP,因为它们必须使用许多 if
语句来找到合适的子类构造函数。
我还在 Java 中找到了 a similar question 如何做到这一点。但是我不知道它是否可以在打字稿中实现。
我不知道这是否是一个好习惯,但您可以通过随机访问而不是顺序访问来避免大量 if 语句 class。
你可以试试这样的方法:
enum Behaviour {
Friendly = 0,
Agressive
}
export abstract class BaseCharacter{
protected strength: number;
public canFightWith(character: BaseCharacter): Boolean{
return this.getBehaviour() !== character.getBehaviour();
}
public getStrength():number{
return this.strength;
}
public abstract getBehaviour():Behaviour;
}
export class Vilain extends BaseCharacter{
private reduction;
public Vilain(strength:number, reduction:number){
this.strength = strength;
this.reduction = reduction;
}
public getStrength():number{
return super.getStrength()*this.reduction;
}
public getBehaviour(): Behaviour {
return Behaviour.Agressive;
}
}
export class Hero extends BaseCharacter{
public Hero(strength:number){
this.strength = strength
}
public getBehaviour(): Behaviour {
return Behaviour.Friendly;
}
}
export class StaticFactory{
// in this example Hero and Vilain will extend BaseCharacter
static definitions = {
'hero':Hero,
'vilain':Vilain
}
static instanciateCharacter(subClass: string, ...args):BaseCharacter {
if(subClass in StaticFactory.definitions)
return new StaticFactory.definitions[subClass](...args);
}
}
export class Battle{
public constructor(private first: BaseCharacter, private second: BaseCharacter){
if(!this.first.canFightWith(second))
throw new Error("These 2 characters fight for the same cause !");
}
public getWinner():BaseCharacter{
if (this.first.getStrength() === this.second.getStrength())
return !(Math.trunc(Math.random()*2))?this.first:this.second;
return this.first.getStrength() > this.second.getStrength()?this.first:this.second;
}
}
我刚刚学习了工厂模式并想在 Typescript 中实现它。
我检查了很多站点,例如 this,并注意到所有示例都违反了 OCP,因为它们必须使用许多 if
语句来找到合适的子类构造函数。
我还在 Java 中找到了 a similar question 如何做到这一点。但是我不知道它是否可以在打字稿中实现。
我不知道这是否是一个好习惯,但您可以通过随机访问而不是顺序访问来避免大量 if 语句 class。
你可以试试这样的方法:
enum Behaviour {
Friendly = 0,
Agressive
}
export abstract class BaseCharacter{
protected strength: number;
public canFightWith(character: BaseCharacter): Boolean{
return this.getBehaviour() !== character.getBehaviour();
}
public getStrength():number{
return this.strength;
}
public abstract getBehaviour():Behaviour;
}
export class Vilain extends BaseCharacter{
private reduction;
public Vilain(strength:number, reduction:number){
this.strength = strength;
this.reduction = reduction;
}
public getStrength():number{
return super.getStrength()*this.reduction;
}
public getBehaviour(): Behaviour {
return Behaviour.Agressive;
}
}
export class Hero extends BaseCharacter{
public Hero(strength:number){
this.strength = strength
}
public getBehaviour(): Behaviour {
return Behaviour.Friendly;
}
}
export class StaticFactory{
// in this example Hero and Vilain will extend BaseCharacter
static definitions = {
'hero':Hero,
'vilain':Vilain
}
static instanciateCharacter(subClass: string, ...args):BaseCharacter {
if(subClass in StaticFactory.definitions)
return new StaticFactory.definitions[subClass](...args);
}
}
export class Battle{
public constructor(private first: BaseCharacter, private second: BaseCharacter){
if(!this.first.canFightWith(second))
throw new Error("These 2 characters fight for the same cause !");
}
public getWinner():BaseCharacter{
if (this.first.getStrength() === this.second.getStrength())
return !(Math.trunc(Math.random()*2))?this.first:this.second;
return this.first.getStrength() > this.second.getStrength()?this.first:this.second;
}
}