模块化与类(newInstance, get , set)

本文档详细介绍了如何使用JavaScript创建类、实例化对象、属性的默认值设定、属性的访问和设置方法,以及类的继承机制。通过`macro.newInstance`和`extend`方法实现对象的实例化和扩展,`vtkFullScreenRenderWindow`展示了如何定义类的特定方法,如`setControllerVisibility`和`toggleControllerVisibility`。同时,文章还阐述了如何通过`macro.setGet`来暴露对象的get和set方法,以便于属性的访问和修改。
类的定义与导出
 
都以这种方式导出类, 类.newInstance获取类实例,内部通过 publicAPI来定义类方法,model管理类属性
 
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {        //输入参数
  background: [0.32, 0.34, 0.43],
  listenWindowResize: true,
  container: null,
};

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);
  console.log('publicapi',publicAPI)
  // Object methods
  macro.obj(publicAPI, model);
  macro.get(publicAPI, model, [
    'renderWindow',
    'renderer',
    'openGLRenderWindow',
    'interactor',
    'rootContainer',
    'container',
    'controlContainer',
  ]);


  // Object specific methods
  vtkFullScreenRenderWindow(publicAPI, model);
}


// ----------------------------------------------------------------------------


export const newInstance = macro.newInstance(extend);

// ----------------------------------------------------------------------------

export default { newInstance, extend };

 

一个类模块导出方法newInstance和extend ,
newInstance方法调用macro.newInstance方法来创建新的实例
extend方法用于类继承
 
创建实例
一个类模块导出方法newInstance
newInstance方法调用macro.newInstance方法来创建新的实例
 
macro.newInstance
export function newInstance(extend, className) {
  const constructor = (initialValues = {}) => {
    const model = {};
    const publicAPI = {};
    extend(publicAPI, model, initialValues);

    return Object.freeze(publicAPI);
  };

  // Register constructor to factory
  if (className) {
    vtk.register(className, constructor);
  }

  return constructor;
}

 

 
 
内部方法的定义
 
function vtkFullScreenRenderWindow(publicAPI, model) {
  publicAPI.setControllerVisibility = (visible) => {
    model.controllerVisibility = visible;
    if (model.controlContainer) {
      if (visible) {
        model.controlContainer.style.display = 'block';
      } else {
        model.controlContainer.style.display = 'none';
      }
    }
  };


  publicAPI.toggleControllerVisibility = () => {
    publicAPI.setControllerVisibility(!model.controllerVisibility);
  };

}

 

 
属性:
 
默认属性的定义
const DEFAULT_VALUES = {
  radius: 1.0,
  resolution: 6,
  center: [0, 0, 0],
  pointType: 'Float32Array',
  lines: false,
  face: true,
};
export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);
    ...
}
export const newInstance = macro.newInstance(extend, 'vtkCircleSource');

通过调用newInstance方法传参来设置属性

CircleSource.newInstance({ radius: 1, resolution: 80, lines: true, face: false });

 

属性的访问:
 
通过macro.setGet  macro.setGetArray等方法为属性加上get/set方法来暴露属性:
  macro.setGet(publicAPI, model, ['radius', 'resolution', 'lines', 'face']);
  macro.setGetArray(publicAPI, model, ['center'], 3);

 

如上面暴露了方法:
setRadius()
getRadius()

 

 
 
macro.setGet源码:(macro是一个语法糖工具用于为对象提供一定特别功能)
export function setGet(publicAPI, model, fieldNames) {
  get(publicAPI, model, fieldNames);
  set(publicAPI, model, fieldNames);
}

export function get(publicAPI, model, fieldNames) {
  fieldNames.forEach((field) => {
    if (typeof field === 'object') {
      publicAPI[`get${capitalize(field.name)}`] = () => model[field.name];
    } else {
      publicAPI[`get${capitalize(field)}`] = () => model[field];
    }
  });
}

export function set(publicAPI, model, fields) {
  fields.forEach((field) => {
    if (typeof field === 'object') {
      publicAPI[`set${capitalize(field.name)}`] = findSetter(field)(
        publicAPI,
        model
      );
    } else {
      publicAPI[`set${capitalize(field)}`] = findSetter(field)(
        publicAPI,
        model
      );
    }
  });
}

 

 
 
 
继承
 
每个类的定义都是一个extend方法来扩展publicAPI对象和数据模型对象model,同时这个extend方法被导出,
继承通过类名.extend方式来让publicAPI和model继承父类方法属性。
 
如下:
vtkCellArray 继承于vtkDataArray
 
export function extend(publicAPI, model, initialValues = {}) {
    vtkDataArray.extend(publicAPI, model, initialValues);
}

 

<think>我们正在分析以下三行代码: ```csharp private static Operate _instance; public static Operate Instance => _instance ??= new Operate(); public DataStore DataStore { get; set; } = new DataStore(); ``` 这三行代码位于`Operate`中,该被设计为单例模式。下面逐行分析: 1. `private static Operate _instance;` - 声明了一个私有的静态变量`_instance`,型为`Operate`。这个变量用于存储`Operate`的唯一实例。由于是静态的,它在整个应用程序生命周期内存在,并且是私有的,因此不能从外部直接访问。 2. `public static Operate Instance => _instance ??= new Operate();` - 定义了一个公共的静态属性`Instance`,用于获取`Operate`的单例实例。该属性使用Lambda表达式(=>)定义,是一个只读属性。 - 当访问`Instance`属性时,它会检查`_instance`是否为null。如果为null,则使用`new Operate()`创建一个新的`Operate`实例并赋值给`_instance`(`??=`操作符的作用是:如果左侧为null,则计算右侧表达式并赋值给左侧,然后返回结果)。如果不为null,则直接返回现有的实例。 - 这样确保了在整个应用程序中,`Operate`只有一个实例(单例模式)。 3. `public DataStore DataStore { get; set; } = new DataStore();` - 定义了一个公共的实例属性`DataStore`,型为`DataStore`。该属性具有getset访问器,表示可读写。 - 在声明时,通过`= new DataStore()`进行了初始化。这意味着每当创建一个`Operate`实例(即单例实例被创建时),`DataStore`属性会被自动初始化为一个新的`DataStore`对象。这样,在单例实例中,`DataStore`属性就指向一个唯一的`DataStore`对象,用于存储所有的数据(年级、班级、学生)。 ### 作用总结 - 这三行代码共同实现了`Operate`的单例模式,确保整个系统中只有一个`Operate`实例。 - 同时,在单例实例中初始化了一个`DataStore`对象,作为整个应用程序的数据存储中心。 - 通过`Operate.Instance`可以全局访问这个单例,进而访问其`DataStore`属性,实现数据的统一管理。 ### 相关问题 根据以上分析,生成三个相关问题: §§相关问题§§ 1. 在单例模式中,为什么将_instance声明为private? 2. 使用??=操作符使用if判断null有何区别? 3. 在Operate中,DataStore属性为什么在声明时直接初始化为new DataStore()?</think>### 代码分析 在`Operate`中,这三行代码共同实现了**单例模式**和**数据存储初始化**的核心功能: ```csharp private static Operate _instance; public static Operate Instance => _instance ??= new Operate(); public DataStore DataStore { get; set; } = new DataStore(); ``` #### 1. 单例模式实现 - **`private static Operate _instance;`** 声明一个私有静态字段,用于保存的唯一实例。`private`修饰符确保外部无法直接访问,`static`保证在内存中仅存在一个实例。 - **`public static Operate Instance => _instance ??= new Operate();`** - 使用`??=`操作符实现**线程安全的懒加载单例**: - 当首次访问`Instance`时,若`_instance`为`null`,则创建新实例并赋值 - 后续访问直接返回已存在的实例 - `=>`语法定义只读属性,等效于: ```csharp get { return _instance ?? (_instance = new Operate()); } ``` #### 2. 数据存储初始化 - **`public DataStore DataStore { get; set; } = new DataStore();`** - 在`Operate`实例创建时自动初始化`DataStore`对象 - 作为整个系统的**中央数据仓库**,包含: ```csharp public GradeDomain[] GradeDB = new GradeDomain[100]; // 年级存储 public ClassDomain[] ClassDB = new ClassDomain[100]; // 班级存储 public StudentDomain[] StudentDB = new StudentDomain[100]; // 学生存储 ``` ### 核心作用 1. **全局唯一访问点** 通过`Operate.Instance`提供整个系统唯一的操作入口,确保所有模块(如DAO、Controller)共享同一数据源。 2. **数据生命周期管理** 单例模式保证`DataStore`从系统启动到退出全程存在,避免数据不一致。 3. **资源优化** 懒加载机制延迟实例创建,减少不必要的内存开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值