当前位置:编程学习 > C#/ASP.NET >>

求一个好的设计模式

本来以为简单工厂模式能实现的,发现不行。是设计上存在问题吗? 有合适的设计模式吗?
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2
{
    class Father
    {
        public virtual void Calc(object obj1)
        {
        }

        public virtual void Calc(object obj1, object obj2)
        {
        }
    }

    /// <summary>
    /// 子类1只需要一个参数的方法
    /// </summary>
    class Child1 : Father
    {
        public override void Calc(object obj1)
        {
           //
        }

    }

    /// <summary>
    /// 子类2只需要两个参数的方法
    /// </summary>
    class Child2 : Father
    {
        public override void Calc(object obj1, object obj2)
        {
            //
        }
    }

    /// <summary>
    /// 两个子类(可能多个),在Calc时,需要使用不同的资源。
    /// 不需要的资源希望不要一股脑儿全部传给子类方法,子类又不用这个资源。
    /// 以下代码很别扭,感觉工厂模式也不能解决灵活性的问题。
    /// 求高手给出一个好的设计模式
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            MyResource1 res1;
            MyResource2 res2;

            Father someThing = Load(...); //获取子类对象
            if(someThing.GetType() == typeof(Child1))
            {
                someThing.Calc(res1);
            }
            else if(someThing.GetType() == typeof(Child2))
            {
                someThing.Calc(res1,res2);
            }
        }
    }
}
--------------------编程问答-------------------- 使用抽象工厂模式 --------------------编程问答-------------------- 最优雅的设计就是不用任何“设计模式”。 --------------------编程问答-------------------- 既然两个方法不应该放在一起,你干么放到Father中?既然放在Father中,你就应该让Child1和Child2都能把这两个方法跑起来。

你如果为了自己写代码“方便”而把女人跟电梯综合为一个类,这就是纯粹在坑OO的爹呢。不用为了错误的设计而发明设计模式。 --------------------编程问答--------------------
引用 3 楼 sp1234 的回复:
既然两个方法不应该放在一起,你干么放到Father中?既然放在Father中,你就应该让Child1和Child2都能把这两个方法跑起来。

你如果为了自己写代码“方便”而把女人跟电梯综合为一个类,这就是纯粹在坑OO的爹呢。不用为了错误的设计而发明设计模式。


比如Main是工程队,Father是造东西,child1是造平房,child2是造高楼。calc是施工。那么造平房会用到泥沙,可是造高楼除了用泥沙,还要用楼板。 

我的要求是代码中不要有过多的if else, 或者造平房更本不用楼板,楼板资源就不要给了。 --------------------编程问答-------------------- 可不可以在构造的时候选用材料 Father(IMaterial material)
calc作为father的抽象方法 void calc();
IMaterial是通用材料接口,至于高楼材料 IGaolouMaterial : IMeaterial
在child2的calc方法转换一下 --------------------编程问答--------------------     class Father
    {
        public virtual void Calc(object obj1)
        {
        }
 
        public virtual void Calc(object obj1, object obj2)
        {
        }
    }
既然参数都是object类型,那就去掉一个方法
    class Father
    {
        public virtual void Calc(object obj1)
        {
        }
    }
--------------------编程问答-------------------- 装饰模式比较适合你目前的需求 --------------------编程问答-------------------- 工厂模式主要是负责构造对象的~

策略模式主要替换算法~

http://www.cnblogs.com/justinw/archive/2007/02/06/641414.html

该篇也就是《Head First设计模式》第一篇

所以 试试 策略模式
--------------------编程问答-------------------- 坑XX的爹 --------------------编程问答-------------------- 感觉是策略模式,如果是我可能会这样写:


namespace ConsoleApplication2
{
    interface ICalc
    {
        // 考虑到可能多个参数所以用IList<object>, 当然也可以直接用object
        public void Calc(IList<object> obj1);
 
        // 既然不同的Calc可能需要不同的资源,所以定义一个NeedRes,用来告诉Calc的调用者需要准备哪些资源。
        // 这里采用无参形式直接返回带Flag的enum,也可以传入一个enum返回bool,或者其他更好的方法
        public RequireResources NeedRes();
    }
 
    /// <summary>
    /// 子类1只需要一个参数的方法
    /// </summary>
    class Calc1 : ICalc
    {
        //
    }
 
    /// <summary>
    /// 子类2只需要两个参数的方法
    /// </summary>
    class ICalc2 : ICalc
    {
        //
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            ICalc c = Load(...); //获取子类对象
            List<object> res = LoadRes(c.NeedRes()); // 新建 LoadRes 函数用来获取指定的资源

            c.Calc(res);
        }
    }
}
--------------------编程问答-------------------- 没有看出需要模式的地方。
oo里面的多态不就解决了? --------------------编程问答-------------------- 楼主的抽象设计本身有问题

如果
public virtual void Calc(object obj1)
public virtual void Calc(object obj1, object obj2)
这两个方法是2个应该归类为不同抽象行为的方法,那么就不应该放到一起去处理(这将会作为同一个抽象来使用)

而如果楼主觉得在业务上看来,2个Calc方法确实是同一个抽象的2个不同实现,那么就需要看看该如何来抽象你的行为输入数据了,也就是你的MyResource1和MyResource2也应该有一个抽象,比如叫BaseResource,那么你的2个Calc方法就应该合并为一个Calc(BaseResource obj)

作为你的工厂,需要负责的就是制造出匹配的Calc具体实现类和BaseResource具体派生类(这是标准的抽象工厂方法模式),然后在外部来组装调用即可 --------------------编程问答--------------------
引用 4 楼 grayhoundd 的回复:
Quote: 引用 3 楼 sp1234 的回复:

既然两个方法不应该放在一起,你干么放到Father中?既然放在Father中,你就应该让Child1和Child2都能把这两个方法跑起来。

你如果为了自己写代码“方便”而把女人跟电梯综合为一个类,这就是纯粹在坑OO的爹呢。不用为了错误的设计而发明设计模式。


比如Main是工程队,Father是造东西,child1是造平房,child2是造高楼。calc是施工。那么造平房会用到泥沙,可是造高楼除了用泥沙,还要用楼板。 

我的要求是代码中不要有过多的if else, 或者造平房更本不用楼板,楼板资源就不要给了。


按照楼主说的这个例子来举例,你认为在你的系统业务场景里,将施工行为抽象为Father,具体派生出了造平房和造高楼,那么就应该为造平房的原料和造高楼的原料做一个抽象:建筑原材料
造平房的建筑原材料的派生类 就应该是泥沙材料
造高楼的建筑原材料的派生类 就应该为泥沙加楼板的组合材料 --------------------编程问答-------------------- 太坑了,if else 没少写,多写了一个基类
补充:.NET技术 ,  分析与设计
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,