|
Try StarUML[^] - it's free.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys
|
|
|
|
|
|
Thanks guys. Is it good software? Or average?
|
|
|
|
|
StarUML is excellent. We use it to produce all of our design material through it's Word integration.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys
|
|
|
|
|
Pretty reasonable products they are, but as in all software, you have likes and dislikes, some you feel comfortable with, others not so and feel awkward. But try them out and come to your own conclusion.
ArgoUML is written using Java as is Visual Paradigm as is Oracle JDeveloper which includes some degree of UML. Star was written ( I think) with Delphi but as I recall, no longer being developed.
Sparx software via the link in my reply to your latest posting (above) is another paid-for product.
modified 1-Aug-19 21:02pm.
|
|
|
|
|
If I need to sketch something quickly, I use Dia. It's lightweight, has most of the features I normally need, and it doesn't really matter if you're a Windows or a Linux user--you can get a build that fits either: http://live.gnome.org/Dia/Download[^]
|
|
|
|
|
I have a method that could fail for a number of reasons, e.g. an invalid directory, a file not found in that directory, or an entry not found in that file. It's crossed my mind to throw different exceptions for the first two, and return null for the last, but this is not a good practice application of exceptions. My next alternative is to return null for any failure, but this makes unit testing the individual failures difficult. My third option is to return null for any failure, and set an ErrorMessage property on the class. If the method returns null, the caller can read this property and test/report on the error.
|
|
|
|
|
Hi Brady,
IMO you should come up with satisfactory functional specs first, independent of future implementation and/or testing concerns. Once the specs are cast, you can worry about implementing and testing.
You shouldn't burden the user with a more difficult API just because that makes testing easier, should you?
So, will the class user want exceptions? will he be happy with a null return and the need to check something else to find what went wrong?
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
|
|
|
|
|
Luc Pattyn wrote: So, will the class user want exceptions? will he be happy with a null return and the need to check something else to find what went wrong?
The class use is me. I'd prefer the latter, but was wondering if anyone had any caveats with that approach.
|
|
|
|
|
Brady Kelly wrote: The class use is me
I thought as much, but it is rather irrelevant.
Brady Kelly wrote: but was wondering if anyone had any caveats
none here. It is somewhat similar to the Parse/TryParse situation.
They first offered Parse only, which throws whenever it feels like doing so.
Then came TryParse which doesn't tell you anything, except it returns a success flag.
I sometimes return a string, null=OK, non-null=error message (one step better than the old error number, 0=OK, negative=error; unless you need to check for a specific error that is).
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
|
|
|
|
|
Generally I'd go with throwing on any failure - it definitely leads to cleaner code (especially with errors bubbling up the stack and being handled at a convenient place). How you define "failure" then determines the behaviour.
"Entry not found in that file" would depend for me on your model. If every client must have a phone number then GetPhoneNumber(Client) should throw if there isn't one in the file. Either you are throwing an ArgumentException for an invalid client, or you are throwing because there is no phone number for the client - and *something* went wrong, which needs to be fixed.
If they might not have a phone number then returning null to indicate "none" is probably appropriate.
If it returns null when it detects an error, then you are moving the error detection to the client code, which is kinda silly. Theres probably lots of "client" code for the library - and this means you are duplicating a bunch of code. It also means you have created some pretty close coupling as well.
Whatever you do, make sure its clearly documented.
|
|
|
|
|
If the conditions are exceptional then using exceptions is best practice.
If they are not exceptional then you might in some way encapsulate the problem, e.g., the result class, a success/failure flag and optional failure message string. This could be the messaging parameter rather than returning null.
|
|
|
|
|
I have to return something thought, and null is ideal, even if I move away from the client checking for a null return in favour of them checking a success flag or non-null error message, or one and the same.
|
|
|
|
|
I don't know where else to post this, so here goes:
I've been out of touch with TDD for some time, and am very rusty. I'd appreciate some suggestions on how to TDD the method described below.
The method must find a web.config file in a user supplied application directory. It must then extract and return a connection string from that config file. It returns null if for any reason the connection string isn't found, be it a bad path, no web.config, or no connection string in web.config.
My initial thoughts are to write a test with setup that creates a directory and writes a web.config file with a connection string. The test would then call my method with the created path and expect a non-null value back, and my initial test run would fail because my method stub always returns null. Then, implement the method, and run the test expecting a pass. Then, as a pre-test (I forget the term), delete the created directory, and call the method expecting a null value.
|
|
|
|
|
I need to write a very simple WinForms application, but I often get stuck in over analytical mode with these. I get stuck on Yes, No, Retry loops, and with very little thinking to do about the actions of the application, I start thinking about the 'workflow' of the application. Should I just have a method for each task, and call each one sequentially, after checking that the previous didn't raise an 'abort' flag? Should I implement a simple ITask interface, and a class for each task, then loop through an ordered collection of tasks? Should I use this as a simple introduction to Windows Workflow? The scope of this application and its set of tasks is guaranteed to grow, so my first option of hard coding the tasks is the nastiest, but given the size of the app, maintenance can quite easily be done by just changing the code; the executable is always deployed with the upgrade materials, and not permanently deployed.
|
|
|
|
|
I found it hard to find an answerable question. What did strike me was your statement "...guaranteed to grow/hard coding the tasks is the nastiest" followed by "given the size of the app, maintenance can quite easily be done by just changing the code". You seem to have a bit of a conflict.
|
|
|
|
|
I think my sentences ending with question marks are quite easy to answer, even if those without are hard to comment on.
OK, hard coding the tasks is still the nastiest, but the cost of doing this is quite low, so I will be getting into a conflict with management if I can't produce a configurable application in the same time as I can produce a hard-coded one. We're never going to reach even fifty tasks, and if no code is reproduced between tasks, maintaining the hard coded task is feasible enough for the powers that be to sanction a hard-coded app. I, however, do not feel nice about hard coding the app.
|
|
|
|
|
I did have a look at your questions, for example your question: "Should I just have a method for each task, and call each one sequentially, after checking that the previous didn't raise an 'abort' flag?" My answer came to: Possibly, if that what the User wants; which seemed a bit superflous.
Anyway I see you mentioned Windows Workflow. I've never used this but had a look at one of the Intro articles on CP. Workflow looks like it will separate the logic of the task from the details of performing the actions which I'd definitly agree is good.
Having worked both as a software developer and as a manager of s/w developers, what really got to me was developers investing so much time/effort in designing and producing a framework in which to execute tasks (with task interface etc) that the framework became their goal, but as no one else knew the details of this framework it tied, and delayed, the project into using it.
If Worlkflow gives you that framework - which it seems to, I'd use that to develop/code your actions/tasks first and do yout own framework later if its needed. But don't let your management think that the Workflow front-end you may show them is the finished thing if its not. They may assume its a completed front-end.
It looks as if playing with Yes/No/Abort etc is relatively easy in the Workflow and separates from you task objects.
|
|
|
|
|
Jonathan Davies wrote: Possibly, if that what the User wants; which seemed a bit superflous.
This is to a dictatorial application, i.e. it forces the user to do what the project owner, our management, wants. This is a utility to upgrade our main application, and the only user option is the required main application path. 'User' requirements are moot after the task of getting that location.
Jonathan Davies wrote:
Having worked both as a software developer and as a manager of s/w developers, what really got to me was developers investing so much time/effort in designing and producing a framework in which to execute tasks (with task interface etc) that the framework became their goa
Sounds like me sometimes. I used to be worse though.
Thanks for your input.
|
|
|
|
|
I have some basic code for a cache manager provided below. My design is far from complete and I need help. What I need is a single cache manager CacheManager.cs GetCacheItem method that accepts as parameters a cache key, business object delegate method and a variable set of parameters. This manager should be able to get and retrieve items in cache, handle dependencies, and work with every business manager object in the project (i.e. bc_CustomerManager.GetCustomer, bc_ProductManager.GetProduct, etc.) Anyone who can assist me or work with me on this would be wonderful.
Cache Manager GetCacheItem:
public object GetCacheItem(String sCacheKey, QueryExpression QueryExpression, params object[] parameters)
{
object objCacheItem = null;
if (!CachingEnabled)
{
return objCacheItem;
}
if (CacheItem<Object>(sCacheKey) != null)
{
return CacheItem<Object>(sCacheKey);
}
else
{
lock (syncObject)
{
if (CacheItem<Object>(sCacheKey) != null)
{
return CacheItem<Object>(sCacheKey);
}
else
{
Object cacheItem = QueryExpression(parameters);
AddToCache<Object>(sCacheKey, cacheItem);
return cacheItem;
}
}
}
}
In my project I have a business layer and a data layer. I am not sure where and how the code below should be called. Incomplete code call to CacheManager.GetCacheItem:
<pre>
delegate object QueryExpression(params object[] parameters);
CacheManager cacheManager = new CacheManager();
BC_Assects bc_Assects = new BC_Assects();
DataTable dt = (DataTable) cacheManager.GetCacheItem(sCacheKey, bc_Assects.GetAssetsByCollectionID, parameters);
Thank you very much!
Steve
|
|
|
|
|
I got something working. Here is a sample cache manager and aspx page. Now, all I need is to handle dependicies. Can anyone help?
aspx code:
protected void Page_Load(object sender, EventArgs e)
{
CacheManager cacheManager = new CacheManager();
BC_Customer bc_Customer = new BC_Customer();
string[] param1 = { "customers", "stephen", "lisa" };
cacheManager.InsertInCache(bc_Customer.InsertCustomerName, param1);
List<string> cNameList = (List<string>)cacheManager.GetCacheItem(bc_Customer.GetCustomerName, param1);
DropDownList1.DataSource = cNameList;
DropDownList1.DataBind();
string[] param2 = { "products", "Book", "Card" };
BC_Products bc_Products = new BC_Products();
cacheManager.InsertInCache(bc_Products.InsertProductName, param2);
List<string> pNameList = (List<string>)cacheManager.GetCacheItem(bc_Products.GetProductName, param2);
DropDownList2.DataSource = pNameList;
DropDownList2.DataBind();
}
Cache manager:
public delegate object QueryExpression(params object[] parameters);
public delegate object InsertExpression(params object[] parameters);
public class CacheManager
{
public TimeSpan CacheDuration { get; set; }
private static object syncObject = new object();
private bool CachingEnabled = true;
private bool HasKey(string Key)
{
return (HttpContext.Current.Cache[Key] != null);
}
private Object CacheItem(string sCacheKey)
{
return (Object)HttpRuntime.Cache[sCacheKey];
}
public object GetCacheItem(QueryExpression QueryExpression, params object[] param)
{
object objCacheItem = null;
if (!CachingEnabled)
{
return objCacheItem;
}
if (CacheItem((string) param[0]) != null)
{
return CacheItem((string) param[0]);
}
else
{
lock (syncObject)
{
if (CacheItem((string)param[0]) != null)
{
return CacheItem((string) param[0]);
}
else
{
Object cacheItem = QueryExpression(param);
DateTime expiration = DateTime.Now.Add(new TimeSpan (6000));
HttpContext.Current.Cache.Add((string) param[0], (List<string>) cacheItem, null, expiration,
TimeSpan.Zero, System.Web.Caching.CacheItemPriority.Default, null);
return cacheItem;
}
}
}
}
public Object InsertInCache(InsertExpression insertExpression, params object[] param)
{
if (HasKey((string) param[0]))
{
return CacheItem((string)(param[0]));
}
DateTime expiration = DateTime.Now.Add(new TimeSpan (6000));
HttpContext.Current.Cache.Add((string) param[0], insertExpression(param), null, expiration,
TimeSpan.Zero, System.Web.Caching.CacheItemPriority.Default, null);
return CacheItem((string)(param[0]));
}
}
Thanks,
Steve
modified on Saturday, February 28, 2009 10:00 PM
|
|
|
|
|
Now, the cache manager handles dependencies. See below:
public delegate object QueryExpression(params object[] parameters);
public delegate object InsertExpression(params object[] parameters);
public class CacheManager
{
public TimeSpan CacheDuration { get; set; }
private static object syncObject = new object();
private bool CachingEnabled = true;
private bool HasKey(string Key)
{
return ((Object)HttpRuntime.Cache[Key] != null);
}
private Object CacheItem(string sCacheKey)
{
return (Object)HttpRuntime.Cache[sCacheKey];
}
public object GetCacheItem(QueryExpression QueryExpression, params object[] param)
{
object objCacheItem = null;
if (!CachingEnabled)
{
return objCacheItem;
}
if (CacheItem((string) param[0]) != null)
{
return CacheItem((string) param[0]);
}
else
{
lock (syncObject)
{
if (CacheItem((string)param[0]) != null)
{
return CacheItem((string) param[0]);
}
else
{
Object cacheItem = QueryExpression(param);
DateTime expiration = DateTime.Now.Add(new TimeSpan (6000));
HttpContext.Current.Cache.Add((string) param[0], (List<string>) cacheItem, null, expiration,
TimeSpan.Zero, System.Web.Caching.CacheItemPriority.Default, null);
return cacheItem;
}
}
}
}
public Object InsertInCache(InsertExpression insertExpression, params object[] param)
{
System.Web.Caching.CacheDependency cacheDependency;
string[] dependencyKey = { (string) param[1] };
if (HasKey((string) param[0]))
{
return CacheItem((string)(param[0]));
}
DateTime expiration = DateTime.Now.Add(new TimeSpan (6000));
cacheDependency = new System.Web.Caching.CacheDependency(null, dependencyKey);
HttpContext.Current.Cache.Add((string) param[0], insertExpression(param),
(param[1] == "" ? null : (cacheDependency)), expiration,
TimeSpan.Zero, System.Web.Caching.CacheItemPriority.Default, null);
return CacheItem((string)(param[0]));
}
}
|
|
|
|
|
Hi all,
I am workign on vc++. I got a project which is under maintanence now, the project is huge but I am new to this project.Can anybody suggest me a free /trail reverse engineering tool that can give me the design of the project so that i can have a better control on the project.
Thanks in advance...
|
|
|
|
|
|
I do all my reverse engineering with Lattix (www.lattix.com), it gives you a handy dependency matrix, with which you can play and restructure your application in a nice way. It is not free, but you can download a trial that might help you out in a couple of days. It works in combo with dOxygen.
If you download refer to me and they provide you some more help.
Han
|
|
|
|
|