如何把现有代码改成 工厂模式,OOP,AOP模式?

MMX1027 2006-12-19 10:28:56
我的代码现在是如下结构:一个主函数,用来根据接收参数来判断该执行哪个子功能。每个子功能都有一个相同名字的处理函数,但参数有可能不相同。
public class MainClass{

public static main(String arg[]){
if("参数1".equals(arg[0])){
ClassA ca = new ClassA();
ca.getData();
}
else if("参数2".equals(arg[0])){
ClassB cb = new ClassB();
cb.getData("参数");
}
else if("参数3".equals(arg[0])){
ClassC cc = new ClassC();
cc.getData(整数1);
}
else if("参数4".equals(arg[0])){
ClassD cd = new ClassD();
cd.getData(整数1,2);
}
.....
}

}

public class ClassA{

public getData(){
...
}
}
...
public class ClassD{

public getData(int i,int j){
...
}
}

现在发现随着业务的新增和不断变化,主函数里里的 if ... else if ... 语句越写越多
有没有办法把这些代码规划得更有层次一些?
最近在看一些关于设计模式的文章,但对 工厂模式 OOP 等概念不是很了解。
想请大侠们就现在这个代码状况,把它改造得更有层次一些,扩展性更强一些。
谢谢。

例如,建一个工厂类,所有的业务处理类都派生于这个工厂,根据传来的参数通知工厂创建相应的业务处理类,执行相应的处理函数。
下一步是按照Spring的一些功能,用配置文件实现业务逻辑的可配置。
不知道我这样描述对不对。请各位大侠指教。

本问题的另一个帖子,在基础版
http://community.csdn.net/Expert/topic/5239/5239970.xml?temp=2.662295E-02

...全文
244 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
MMX1027 2006-12-22
  • 打赏
  • 举报
回复
感谢楼上 nirvana_li(东成西就,芝兰境界) 的关注。
等待...
nirvana_li 2006-12-22
  • 打赏
  • 举报
回复
上面的例子是不完整的,楼主可以结合petshop的代码理解。也可以参考DAO(数据访问对象)模式。

再补充一下,楼主所举的例子过于抽象,我的理解可能和楼主的理解有出入。所以我做了不同的假设。如果这些假设不成立,用抽象工厂的方式也是不正确的。所以对模式的应用必须要有对应的Context(《设计模式》中反复出现,中文硬译为“上下文”,但我觉得和“背景”“环境”这样的词更贴近……)。
nirvana_li 2006-12-22
  • 打赏
  • 举报
回复
我的假设:
第一,参数包含的信息合进行对象的实例化之间有关系。
第二,各个对象之间没有关系,即ClassA,ClassB……没有关系,它们之间也无法泛化出公共基类。
第二,根据实例化的对象调用相应的参数。

针对第一种情况:使用反射来解决不同对象实例化,而不是通过if-else判断。
针对第二种情况:要分离业务的关注点,所有的ClassA,ClassB……我们可以将它的状态和行为进行分离。
针对第三种情况:因为行为都是相关对象自己的,也就是说classA 的 GetData()和classB的GetData(string param)是没有任何相关性的,所以隔离在各自的类当中。

举一个例子:就是.net的PetShop4中的数据访问对象(DAO)的实现(基于抽象工厂模式)来说明:
首先是Model。也就是领域模型
public class CategoryInfo {

private string id;
public CategoryInfo() { }
......

// Properties
public string Id {
get { return id; }
}
……

这样一个只具有属性和getter,setter的类。
public interface ICategory {
IList<CategoryInfo> GetCategories();
CategoryInfo GetCategory(string categoryId);
}
ICategory其实就是将Category类的行为进行分离的一个接口。具体的行为实现在petshop中有两种,一种是SQLServer中的Category一种是Oracle中的Category。

真正的工厂是DataAccess:
public sealed class DataAccess {

// Look up the DAL implementation we should be using
private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
private static readonly string orderPath = ConfigurationManager.AppSettings["OrdersDAL"];

private DataAccess() { }

public static PetShop.IDAL.ICategory CreateCategory() {
string className = path + ".Category";
return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
}
……
它通过反射来创建不同的领域对象。
而它的客户端程序(BLL业务逻辑层)通过:
public class Category {

// Get an instance of the Category DAL using the DALFactory
// Making this static will cache the DAL instance after the initial load
private static readonly ICategory dal = PetShop.DALFactory.DataAccess.CreateCategory();

/// <summary>
/// Method to get all categories
/// </summary>
/// <returns>Generic List of CategoryInfo</returns>
public IList<CategoryInfo> GetCategories() {
return dal.GetCategories();
}

/// <summary>
/// Search for a category given it's unique identifier
/// </summary>
/// <param name="categoryId">Unique identifier for a Category</param>
/// <returns>A Category business entity</returns>
public CategoryInfo GetCategory(string categoryId) {

// Validate input
if (string.IsNullOrEmpty(categoryId))
return null;

// Use the dal to search by category Id
return dal.GetCategory(categoryId);
}
……
MMX1027 2006-12-21
  • 打赏
  • 举报
回复
UP
nirvana_li 2006-12-21
  • 打赏
  • 举报
回复
分析一下楼主提出的问题:
楼主写的代码我理解到问题有两方面:
1. 对象创建的易变性。楼主在if-else中包含了都是对对象创建的hardcode。而且也提到为了满足开闭原则,希望能够使用模式解决该问题。
2. 楼上的也提到了各个对象中存在getData的不同参数的情况。这也是一个变化点。这属于对象行为的可变性。

下班了,标记一下,明天再来。
kason_j 2006-12-20
  • 打赏
  • 举报
回复
但是,我覺得你這個例子運用工廠模式好像行不通吧,用抽象工廠好像也不行,因為你的子類方法的參數不同.
還得好好考慮一下.
kason_j 2006-12-20
  • 打赏
  • 举报
回复
// 水果基类
public class Fruit;

// 苹果是一种水果
public class Apple : Fruit;

// 句子是一种水果
public class Orange : Fruit;


// 水果工厂类
public class FruitFactory
{
// 根据水果名称制造一个水果对象
public static Fruit CreateInstance(string fruitName)
{
if(fruitName=="APPLE")
return new Apple();
else if(fruiteName=="ORANGE")
return new Orange();
else
return null;
}
}
// 制造一个Apple对象,即:new Apple();
Apple anApple=(Apple)FruitFactory.CreateInstance("APPLE");
// 制造一个Orange对象,即:new Orange();
Orange anOrange=(Orange)FruitFactory.CreateInstance("ORANGE");
MMX1027 2006-12-20
  • 打赏
  • 举报
回复
感谢楼上的批评,目前在学习中...
superhasty 2006-12-20
  • 打赏
  • 举报
回复
可以用职责链模式。
xiaoyetao08 2006-12-19
  • 打赏
  • 举报
回复
天哪
你对模式究竟理解了多少???

不要什么都不懂,就模式.
看来楼主敲代码功夫还得深入啊

50,528

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧