我们一起来读书吧 关注:153贴子:2,640
  • 0回复贴,共1

代码里的世界观第5-6章

只看楼主收藏回复

Service Locator
它是编程原则 “控制反转”(roe) 的实现方式之一。 控制反转是“某种权力转交给了别人,于是被反转了” 。 在 ServiceLocator里, 就是“你创建对象的权力转移给 Container了”, 被 “反转”了。
实现“控制反转”有第二种方式是依赖注入。 例如,通过属性注入这种依赖注入的方式。自然也可以把创建对象的任务外包,交给外层,从而实现“控制反转”。
控制反转的两种手法,再集成工厂模式 ,可能让本不需要 new的模块里 ,彻底摆脱 new, 从而整体升级到抽象层面 。
领域驱动设计”( DDD )的概念
对象可以分为两种:实体对象和值对象。 两者有啥区别呢? 形象 一点说,在一个戏台上,演主角的,就是实体对象;演路人甲或者道具布景之类的,就是值对象。
实体对象有啥特点呢?既然是主角,肯定会有唯一标识。
值对象就是那些我们不关心它具体标识的对象。 它们仅仅给实体对象提供一些标准化的服务。
分清两者对我们的意义如下 。
封装对象的时候,能更清晰地将值对象的数据从实体对象里区分出来。
给我们设计对象依赖关系带来一个指导纲领:我们应该尽量让实体对象能拥有值对象, 而不要出现值对象去拥有实体对象的情况 。
描述数据的数据
用代码描述的数据
class student {
public string name;
public int age ;
}
用数据来描述的数 据
服务器里的数据是 XML格式的
<?xml version="1.0" encoding="gb2312"?>
<studentlist>
<student id=”A101">
<name>小华 </name>
<age>22</age>
我们通过一个 XSD文件来描述上面这个 XML文件的格式,这个 XSD文件就是元数据。
<?xml version="l.0" encoding=”utf-8” ?>
<xs:schema id="student">
<xs :element name="student">
<xs : complexτype>
<xs :sequence>
<xs :element name="name" type="nameType"/>
<xs·element ref="age"/>
如果添加了一个字段,例如 sex,重新修改 XSD 文件,再重新生成一遍,就可以得到新的 student 类 。
在自动生成代码领域,元数据用得会比较深入。
数据驱动一一把变化抽象成数据
辅助技术: 反射
三个案例
案例 1 :
bool isValidFileType (string type) {
bool isValid =false;
if(type ==”mp4”){
isValid = true;
}else if(type ==”txt") {
isValid = true ;
}
}
之前的代码, 等于把整个 validTypeArray 里面的数据像面粉一样发酵起来了,代码膨胀且缺乏弹性
string[] validTypeArray = {"mp4", "txt" ,"ppt", "pptx", "pdf",
"xls", "xlsx", "doc", "docx" };
bool isValidFileType (string type) {
return validTypeArray .Contains (type) ;

案例 2:大智若愚的应对
遇到一个特殊数据,需要额外进行逻辑处理
if (number == "123") {
DoSomeThing () ;

如果下次增加了一个新的特殊数据 ”456”,又要修改 if 的内容,
// 首先定义一个数组去承载这些特殊数据
Array exceptionNumbers = {"123", "456"};
// 接着定义一个判断函数
bool isExceptionNumber (string number) {
return exceptionNumbers. Contains (number) ;

后者有如下几点优势。
在数据驱动方法里, 抽象 出一个新的函数 isExceptionNumber(string number),这 个函数名承载了语境,让人一看就懂 。
在数据驱动方法里,修改影响的作用域不一样了
在数据驱动方法里 , 数据源可以转换形式 , 更改位置 。
案例 3:以不变应万变
系统里有 20个不同的子类,界面上有 20个按钮。 每单击一个按钮,就创建一个对应的子类 对象 。 于是足足实现了 20个点击事件,其中第一个事件的实现代码如下:
void button1_click(object sender) {
BaseClass obj = new Class1 () ;
}
那么如果是下拉列表框中选中事件的代码,合理的设计怎么实现呢 ?
准备一张字典或散列表来装载表示 button 和对象之 间映射关系的数据
[
button1_tag : "Class1",
button2_tag : "Class2",
button3_tag : "Class3",
.....button20_tag : "Class20"
]
引擎代码,引擎代码是描述规则的代码,也是框架代码的核心
// 这里的规则简单:先找到对象名,就可以创建对象了
BaseClass GenerateClass (string button_tag) {
string className = dic[button_tag];
Class<?> currentClass = Class. forName (className) ;
return currentClass.newInstance () ;}
调用引擎代码
// 接下来能很方便地创建对象了
void DropDownList_Selected (string selectedItem) /
BaseClass obj = GenerateClass (selectedItem) ;
}
而这一步的代码和前两步代码是明显 隔离的,甚至可以在不同模块里完成,这将带来很好的灵活性 。
从这些案例可以看到:数据驱动能让你的代码灵活,把变化放在了最能够容纳变化的容器里


IP属地:北京1楼2024-06-18 17:45回复